home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / graphics / mandelv2.3 < prev    next >
Internet Message Format  |  1989-06-21  |  69KB

  1. Path: xanth!ames!oliveb!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i154:  mandelvroom - mandelbrot explorer v2.0, Part03/09
  5. Message-ID: <111388@sun.Eng.Sun.COM>
  6. Date: 21 Jun 89 04:01:18 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2676
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: kevin@uts.amdahl.com (Kevin Clague)
  12. Posting-number: Volume 89, Issue 154
  13. Archive-name: graphics/mandelv20.3
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    gadgets.c
  24. #    getfile.c
  25. #    getfile.h
  26. #    getint.c
  27. #    help.c
  28. #    hist.c
  29. #    iffw.c
  30. # This is archive 3 of a 9-part kit.
  31. # This archive created: Tue Jun 20 20:45:27 1989
  32. echo "extracting gadgets.c"
  33. sed 's/^X//' << \SHAR_EOF > gadgets.c
  34. X/*
  35. X * MandelVroom 2.0
  36. X *
  37. X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  38. X *
  39. X * All rights reserved.
  40. X *
  41. X * Permission is hereby granted to distribute this program's source
  42. X * executable, and documentation for non-comercial purposes, so long as the
  43. X * copyright notices are not removed from the sources, executable or
  44. X * documentation.  This program may not be distributed for a profit without
  45. X * the express written consent of the author Kevin L. Clague.
  46. X *
  47. X * This program is not in the public domain.
  48. X *
  49. X * Fred Fish is expressly granted permission to distribute this program's
  50. X * source and executable as part of the "Fred Fish freely redistributable
  51. X * Amiga software library."
  52. X *
  53. X * Permission is expressly granted for this program and it's source to be
  54. X * distributed as part of the Amicus Amiga software disks, and the
  55. X * First Amiga User Group's Hot Mix disks.
  56. X *
  57. X * contents:  this file contains tools to allocate and free gadgets and
  58. X * gadget imagery for MandelVroom.
  59. X */
  60. X
  61. X#include "mandp.h"
  62. X
  63. X#define TOP 1
  64. X#define BOT 2
  65. X
  66. X/*************************************************************************
  67. X *
  68. X * Allocate and ititialize gadget tools
  69. X *
  70. X ************************************************************************/
  71. X
  72. X/*
  73. X * Make a generic boolean gadget
  74. X */
  75. Xstruct Gadget *MakeBool(x,y,xd,yd,c,id, flags)
  76. X  SHORT  x,y,xd,yd;
  77. X  UBYTE  c;
  78. X  USHORT id;
  79. X  USHORT flags;
  80. X{
  81. X  register struct Gadget *NewGadget;
  82. X  register struct Image  *NewImage,*ShadowImage;
  83. X
  84. X  NewGadget = (struct Gadget *)
  85. X    safeAllocMem( (ULONG) sizeof(struct Gadget), (LONG) MEMF_CLEAR );
  86. X
  87. X  if (NewGadget == NULL) return( NewGadget );
  88. X
  89. X  if ( flags & GADGIMAGE ) {
  90. X
  91. X    NewImage = (struct Image *)
  92. X      safeAllocMem( (ULONG) sizeof(struct Image), (LONG) MEMF_CLEAR );
  93. X
  94. X    if ( NewImage == NULL ) {
  95. X      FreeMem( (char *) NewGadget, (LONG) sizeof(struct Gadget));
  96. X      return( NULL );
  97. X    }
  98. X
  99. X    ShadowImage = (struct Image *)
  100. X      safeAllocMem( (ULONG) sizeof(struct Image), (LONG) MEMF_CLEAR );
  101. X
  102. X    if ( ShadowImage == NULL ) {
  103. X      FreeImage( NewImage );
  104. X      FreeMem( (char *) NewGadget, (LONG) sizeof(struct Gadget));
  105. X      return( NULL );
  106. X    }
  107. X
  108. X    NewImage->Width = xd;
  109. X    NewImage->Height = yd;
  110. X    NewImage->PlaneOnOff = c;
  111. X
  112. X    ShadowImage->LeftEdge = 1 + XScale;
  113. X    ShadowImage->TopEdge = 1 + YScale;
  114. X    ShadowImage->Width = xd;
  115. X    ShadowImage->Height = yd;
  116. X    ShadowImage->PlaneOnOff = SHADOWPEN;
  117. X    ShadowImage->NextImage = NewImage;
  118. X
  119. X    NewGadget->GadgetRender = (APTR) ShadowImage;
  120. X
  121. X  } else {
  122. X
  123. X    NewGadget->GadgetRender = (APTR)
  124. X                              ShadowBorder( BEVELEDUP, 1, 1, xd-1, yd-1 );
  125. X  }
  126. X
  127. X  NewGadget->LeftEdge = x;
  128. X  NewGadget->TopEdge  = y;
  129. X  NewGadget->Width    = xd;
  130. X  NewGadget->Height   = yd;
  131. X  NewGadget->Flags    = GADGHCOMP | flags;
  132. X  NewGadget->Activation = GADGIMMEDIATE;
  133. X  NewGadget->GadgetType = BOOLGADGET;
  134. X  NewGadget->GadgetID = id;
  135. X
  136. X  return(NewGadget);
  137. X} /* MakeBool */
  138. X
  139. X/*
  140. X * Make a generic potentiometer gadget
  141. X */
  142. Xstruct Gadget *MakePot(x, y, xd, yd, id, cnt)
  143. X  SHORT  x,y,xd,yd;
  144. X  USHORT id;
  145. X  USHORT cnt;
  146. X{
  147. X  register struct Gadget   *NewGadget;
  148. X  register struct Image    *NewImage;
  149. X  register struct PropInfo *NewInfo;
  150. X
  151. X  NewGadget = (struct Gadget *)
  152. X    safeAllocMem( (ULONG) sizeof(struct Gadget), MEMF_CLEAR );
  153. X
  154. X  if (NewGadget == NULL) goto nogadget;
  155. X
  156. X  NewImage = (struct Image *)
  157. X    safeAllocMem( (ULONG) sizeof(struct Image), MEMF_CLEAR );
  158. X
  159. X  if (NewImage == NULL) goto noimage;
  160. X
  161. X  NewInfo = (struct PropInfo *)
  162. X    safeAllocMem( (ULONG) sizeof(struct PropInfo), MEMF_CLEAR );
  163. X
  164. X  if (NewInfo == NULL) goto noinfo;
  165. X
  166. X  NewGadget->LeftEdge = x;
  167. X  NewGadget->TopEdge  = y;
  168. X  NewGadget->Width    = xd;
  169. X  NewGadget->Height   = yd;
  170. X  NewGadget->Flags    = GADGHIMAGE | GADGIMAGE;
  171. X  NewGadget->Activation   = RELVERIFY;
  172. X  NewGadget->GadgetType   = PROPGADGET;
  173. X  NewGadget->GadgetRender = (APTR) NewImage;
  174. X  NewGadget->SpecialInfo  = (APTR) NewInfo;
  175. X  NewGadget->GadgetID     = id;
  176. X
  177. X  NewImage->PlaneOnOff = SHADOWPEN;
  178. X  NewImage->Width  = 4 << XScale;
  179. X  NewImage->Height = 3 << YScale;
  180. X
  181. X  NewInfo->Flags = PROPBORDERLESS | FREEVERT;
  182. X  NewInfo->VertBody = 1;
  183. X
  184. X  return(NewGadget);
  185. X
  186. Xnoinfo:
  187. X  FreeMem( (char *) NewImage,  (LONG) sizeof(struct Image));
  188. X
  189. Xnoimage:
  190. X  FreeMem( (char *) NewGadget, (LONG) sizeof(struct Gadget));
  191. X
  192. Xnogadget:
  193. X  return( NULL );
  194. X} /* MakePot */
  195. X
  196. X/*
  197. X * Make a generic string gadget
  198. X */
  199. Xstruct Gadget *MakeString( x, y, length, id, String )
  200. X  SHORT  x,y,length;
  201. X  USHORT id;
  202. X  char *String;
  203. X{
  204. X  register struct Gadget     *NewGadget;
  205. X  register struct StringInfo *NewString;
  206. X  register struct Border     *Border;
  207. X
  208. X  register char *NewBuffer;
  209. X
  210. X  NewGadget = (struct Gadget *)
  211. X    safeAllocMem( (ULONG) sizeof(struct Gadget), (LONG) MEMF_CLEAR );
  212. X
  213. X  if ( NewGadget == NULL ) goto nogadget;
  214. X
  215. X  NewString = (struct StringInfo *)
  216. X    safeAllocMem( (ULONG) sizeof(struct StringInfo), (LONG) MEMF_CLEAR );
  217. X
  218. X  if (NewString == NULL) goto nostring;
  219. X
  220. X  NewBuffer = (char *) safeAllocMem( (ULONG) length + 1, (LONG) MEMF_CLEAR );
  221. X
  222. X  if (NewBuffer == NULL) goto nobuffer;
  223. X
  224. X  Border = ShadowBorder( BEVELEDDOWN, -1, -1, length * 8 + 1, 9 );
  225. X
  226. X  NewGadget->LeftEdge = x;
  227. X  NewGadget->TopEdge  = y;
  228. X  NewGadget->Width    = length * 8;
  229. X  NewGadget->Height   = 8;
  230. X  NewGadget->Flags    = GADGHCOMP;
  231. X  NewGadget->Activation = STRINGRIGHT;
  232. X  NewGadget->GadgetType = STRGADGET;
  233. X  NewGadget->GadgetID = id;
  234. X  NewGadget->GadgetRender = (APTR) Border;
  235. X  NewGadget->SpecialInfo  = (APTR) NewString;
  236. X
  237. X  NewString->MaxChars = length + 1;
  238. X  NewString->BufferPos = 0;
  239. X  NewString->DispPos = 0;
  240. X  NewString->Buffer = (UBYTE *) NewBuffer;
  241. X
  242. X  strcpy( NewBuffer, String );
  243. X
  244. X  return(NewGadget);
  245. X
  246. Xnobuffer:
  247. X
  248. X  FreeMem( (char *) NewString, (long) sizeof( struct StringInfo ) );
  249. X
  250. Xnostring:
  251. X
  252. X  FreeMem( (char *) NewGadget, (long) sizeof( struct Gadget ) );
  253. X
  254. Xnogadget:
  255. X
  256. X  return( NULL );
  257. X
  258. X} /* MakeString */
  259. X
  260. X/*
  261. X * Free a string of gadgets
  262. X */
  263. XFreeGadgets(FirstGadget)
  264. X  struct Gadget *FirstGadget;
  265. X{
  266. X  register struct Gadget *NextGadget;
  267. X  register struct StringInfo *String;
  268. X  register struct Border *Render;
  269. X
  270. X  while (FirstGadget) {
  271. X
  272. X    Render = (struct Border *) FirstGadget->GadgetRender;
  273. X
  274. X    if ( Render ) {
  275. X      if (FirstGadget->Flags & GADGIMAGE) {
  276. X
  277. X        FreeImage( (struct Inage *) Render );
  278. X      } else {
  279. X
  280. X        FreeBorder( Render );
  281. X      }
  282. X    }
  283. X
  284. X    Render = (struct Border *) FirstGadget->SelectRender;
  285. X
  286. X    if ( Render ) {
  287. X      if (FirstGadget->Flags & GADGIMAGE) {
  288. X
  289. X        FreeImage( (struct Inage *) Render );
  290. X      } else {
  291. X
  292. X        FreeBorder( Render );
  293. X      }
  294. X    }
  295. X
  296. X    if (FirstGadget->SpecialInfo) {
  297. X
  298. X      switch( FirstGadget->GadgetType ) {
  299. X
  300. X        case PROPGADGET:
  301. X             FreeMem( (char *) FirstGadget->SpecialInfo,
  302. X                      (LONG) sizeof(struct PropInfo));
  303. X             break;
  304. X
  305. X        case STRGADGET:
  306. X             String = (struct StringInfo *) FirstGadget->SpecialInfo;
  307. X             FreeMem( (char *) String->Buffer, (LONG) String->MaxChars );
  308. X             FreeMem( (char *) String, (LONG) sizeof(struct StringInfo));
  309. X
  310. X             break;
  311. X      }
  312. X    }
  313. X
  314. X    FreeIntui( FirstGadget->GadgetText );
  315. X
  316. X    NextGadget = FirstGadget->NextGadget;
  317. X
  318. X    FreeMem( (char *) FirstGadget, (LONG) sizeof(struct Gadget));
  319. X
  320. X    FirstGadget = NextGadget;
  321. X  }
  322. X} /* FreeGadgets */
  323. X
  324. XFreeImage( Image )
  325. X  struct Image *Image;
  326. X{
  327. X  register struct Image *image, *next;
  328. X
  329. X  next = Image;
  330. X
  331. X  while ( image = next ) {
  332. X
  333. X    next = image->NextImage;
  334. X
  335. X    FreeMem( (char *) image, (LONG) sizeof(struct Image));
  336. X  }
  337. X}
  338. X
  339. Xstruct Border *
  340. XMakeShadow( pen, numverts )
  341. X  LONG pen;
  342. X  int numverts;
  343. X{
  344. X  register struct Border *NewBorder;
  345. X  register SHORT *NewCounts;
  346. X
  347. X  NewBorder = (struct Border *)
  348. X    safeAllocMem( (ULONG) sizeof(struct Border), (LONG) MEMF_CLEAR );
  349. X
  350. X  if (NewBorder == NULL) return( NULL );
  351. X
  352. X  NewCounts = (SHORT *)
  353. X    safeAllocMem( (ULONG) sizeof(SHORT) * 2 * numverts, (LONG) MEMF_CLEAR );
  354. X
  355. X  if (NewCounts == NULL) {
  356. X    FreeMem( (char *) NewBorder, (LONG) sizeof(struct Border) );
  357. X    return( NULL );
  358. X  }
  359. X
  360. X  NewBorder->FrontPen = pen;
  361. X  NewBorder->DrawMode = JAM1;
  362. X  NewBorder->XY       = NewCounts;
  363. X  NewBorder->Count    = numverts;
  364. X
  365. X  return( NewBorder );
  366. X}
  367. X
  368. X/*
  369. X * Make an Border structure
  370. X */
  371. Xstatic struct Border *
  372. XMakeCornerShadow( Type, left, top, Width, Height, pen )
  373. X
  374. X           LONG Type;
  375. X  register LONG left,  top;
  376. X           LONG Width, Height;
  377. X           LONG pen;
  378. X{
  379. X  register struct Border *NewBorder;
  380. X  register SHORT *NewCounts;
  381. X
  382. X  register LONG right = left + Width;
  383. X  register LONG bot   = top + Height;
  384. X           LONG cornerx;
  385. X           LONG cornery;
  386. X           LONG direction;
  387. X
  388. X#define NUMVERTS 6
  389. X
  390. X  NewBorder = MakeShadow( pen, NUMVERTS );
  391. X
  392. X  if (NewBorder == NULL) return( NewBorder );
  393. X
  394. X  if ( Type == TOP ) {
  395. X    cornerx = left;  cornery = top; direction = -1;
  396. X  } else {
  397. X    cornerx = right; cornery = bot; direction =  1;
  398. X  }
  399. X
  400. X  NewCounts = NewBorder->XY;
  401. X
  402. X  *NewCounts++ = left;    *NewCounts++ = bot;
  403. X  *NewCounts++ = cornerx; *NewCounts++ = cornery;
  404. X  *NewCounts++ = right;   *NewCounts++ = top;
  405. X
  406. X  left--; top--; bot++; right++;
  407. X  cornerx += direction; cornery += direction;
  408. X
  409. X  *NewCounts++ = right;   *NewCounts++ = top;
  410. X  *NewCounts++ = cornerx; *NewCounts++ = cornery;
  411. X  *NewCounts++ = left;    *NewCounts++ = bot;
  412. X
  413. X  return( NewBorder );
  414. X} /* MakeCornerShadow */
  415. X
  416. Xstruct Border *
  417. XShadowBorder( Type, left, top, xdim, ydim )
  418. X  int Type;
  419. X  int left, top;
  420. X  int xdim, ydim;
  421. X{
  422. X  register struct Border *Border1, *Border2;
  423. X  register int            Pen1,     Pen2;
  424. X
  425. X  if (Type == BEVELEDUP) {
  426. X    Pen1 = HIGHLIGHTPEN; Pen2 = SHADOWPEN;
  427. X  } else {
  428. X    Pen2 = HIGHLIGHTPEN; Pen1 = SHADOWPEN;
  429. X  }
  430. X
  431. X  Border1 = MakeCornerShadow( (long) TOP,  (long) left, (long) top,
  432. X                              (long) xdim, (long) ydim, (long) Pen1 );
  433. X
  434. X  if ( Border1 ) {
  435. X
  436. X    Border2 = MakeCornerShadow( (long) BOT,  (long) left, (long) top,
  437. X                                (long) xdim, (long) ydim, (long) Pen2 );
  438. X    Border1->NextBorder = Border2;
  439. X  }
  440. X
  441. X  return( Border1 );
  442. X}
  443. X
  444. XFreeBorder( Border )
  445. X  struct Border *Border;
  446. X{
  447. X  register struct Border *border, *next;
  448. X
  449. X  next = Border;
  450. X
  451. X  while ( border = next ) {
  452. X
  453. X    next = border->NextBorder;
  454. X
  455. X    FreeMem( (char *) border->XY, (LONG) sizeof(SHORT) * border->Count * 2);
  456. X    FreeMem( (char *) border,     (LONG) sizeof(struct Border));
  457. X  }
  458. X}
  459. X
  460. X
  461. X
  462. X/*
  463. X * Make an IntuiText structure
  464. X */
  465. Xstruct IntuiText *MakeIntui(str, x, y, frontpen, backpen, drawmode )
  466. X  char *str;
  467. X  LONG  x, y;
  468. X  LONG  frontpen, backpen;
  469. X  LONG  drawmode;
  470. X{
  471. X  register struct IntuiText *NewIntui;
  472. X  register char  *NewString;
  473. X
  474. X  NewIntui = (struct IntuiText *)
  475. X    safeAllocMem( (ULONG) sizeof(struct IntuiText), (LONG) MEMF_CLEAR );
  476. X
  477. X  if ( NewIntui == NULL ) return( NULL );
  478. X
  479. X  NewString = (char *)
  480. X    safeAllocMem( (ULONG) strlen( str ) + 1, (LONG) MEMF_CLEAR );
  481. X
  482. X  if ( NewString == NULL ) {
  483. X    FreeMem( (char *) NewIntui, (long) sizeof(struct IntuiText) );
  484. X    return( NULL );
  485. X  }
  486. X
  487. X  NewIntui->FrontPen = frontpen;
  488. X  NewIntui->BackPen  = backpen;
  489. X  NewIntui->DrawMode = drawmode;
  490. X  NewIntui->LeftEdge = x;
  491. X  NewIntui->TopEdge  = y;
  492. X  NewIntui->IText = (UBYTE *) NewString;
  493. X
  494. X  strcpy( NewString, str );
  495. X
  496. X  return(NewIntui);
  497. X} /* MakeIntui */
  498. X
  499. Xstruct IntuiText *
  500. XShadowIntui( str, x, y )
  501. X  char *str;
  502. X  LONG x,y;
  503. X{
  504. X  register struct IntuiText *Intui1, *Intui2, *Intui3;
  505. X
  506. X  Intui1 = MakeIntui( str,  x,     y,     NORMALPEN, NORMALPEN, JAM2 );
  507. X  Intui2 = MakeIntui( str,  x + 1, y + 1, SHADOWPEN, NORMALPEN, JAM2 );
  508. X  Intui3 = MakeIntui( str,  x,     y,     MEDIUMPEN, (long) 0,  JAM1 );
  509. X
  510. X  Intui1->NextText = Intui2;
  511. X  Intui2->NextText = Intui3;
  512. X
  513. X  return( Intui1 );
  514. X}
  515. X
  516. XFreeIntui( Intui )
  517. X  struct IntuiText *Intui;
  518. X{
  519. X  register struct IntuiText *intui, *next;
  520. X
  521. X  next = Intui;
  522. X
  523. X  while ( intui = next ) {
  524. X
  525. X    next = intui->NextText;
  526. X
  527. X    FreeMem( (char *) intui->IText, (long) strlen((char *)intui->IText) + 1);
  528. X    FreeMem( (char *) intui, (LONG) sizeof(struct IntuiText));
  529. X  }
  530. X}
  531. X
  532. X#if 0
  533. Xstruct Border *
  534. XMakeWindowBorder( NewWindow )
  535. X  register struct NewWindow *NewWindow;
  536. X{
  537. X  register struct Border *Border1,*Border2;
  538. X  register SHORT  *Verts;
  539. X  register SHORT  Bottom, Right;
  540. X
  541. X  Border1 = MakeShadow( HIGHLIGHTPEN, 2 );
  542. X
  543. X  if (Border1 == NULL)
  544. X    return NULL;
  545. X
  546. X  Border2 = MakeShadow( SHADOWPEN, 3 );
  547. X
  548. X  if (Border2 == NULL) {
  549. X    FreeBorder( Border1 );
  550. X    return NULL;
  551. X  }
  552. X
  553. X  Bottom = NewWindow->Height - 1;
  554. X  Right  = NewWindow->Width  - 1;
  555. X
  556. X  Verts = Border1->XY;
  557. X
  558. X  /* Vertex.X        Vertext.Y */
  559. X
  560. X  *Verts++ = 0;     *Verts++ = TOPMARG;
  561. X  *Verts++ = 0;     *Verts++ = Bottom;
  562. X
  563. X  Verts = Border2->XY;
  564. X
  565. X  /* Vertex.X        Vertext.Y */
  566. X
  567. X  *Verts++ = 0;     *Verts++ = Bottom;
  568. X  *Verts++ = Right; *Verts++ = Bottom;
  569. X  *Verts++ = Right; *Verts++ = TOPMARG - 1;
  570. X
  571. X  Border1->NextBorder = Border2;
  572. X
  573. X  return( Border1 );
  574. X}
  575. X#endif
  576. SHAR_EOF
  577. echo "extracting getfile.c"
  578. sed 's/^X//' << \SHAR_EOF > getfile.c
  579. X/************************************************************************
  580. Xreq.c
  581. X        This file contains a general-purpose <requester> that
  582. Xwill prompt the user for a filename input.
  583. X        The program actually uses a window instead of a 'Requester'
  584. Xfor greater flexibility. It will take control of your window's
  585. XIDCMP Port when called.
  586. X
  587. X***     This material is copyright (c) 1986 by C. Heath of Microsmiths, Inc.
  588. XPermission is granted to use these files in any way with the following
  589. Xexceptions:
  590. X
  591. X1) The files shall not be posted on any telecommunications service, public
  592. Xor private, except for BIX until January 15, 1987.
  593. X
  594. X2) The files may only be distributed in archive format, with no modifications.
  595. XIf you make any improvements on the file requester and would like to
  596. Xgenerally distribute them, please contact "cheath" on BIX, or write to:
  597. X        Microsmiths Inc, PO Box 561, Cambridge, MA 02140
  598. X
  599. X3) The requester may be used in any commercial product, but must be in
  600. Xobject code format.  You are free to make modifications for use in your
  601. Xproduct.  Permission is granted to Lattice, Inc, and to Manx, Inc, to
  602. Xinclude the source files in archive format.
  603. X
  604. X        Thank you, and enjoy.
  605. X                ...cheath
  606. X
  607. X************************************************************************/
  608. X
  609. X#include "standard.h"
  610. X#include "safeclose.h"
  611. X
  612. X#define FAST register
  613. X#define NL NULL
  614. X
  615. Xextern char *dmore(), *dinit();
  616. X
  617. Xstatic struct FileLock      *pdir = NL;
  618. Xstatic struct FileInfoBlock *dir_info;
  619. X
  620. Xstatic struct Window   *eW;             /* Parent Window. Uck   */
  621. X
  622. Xstatic struct TextAttr MyFont = {"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT };
  623. X
  624. X/* FGAD requires a few unique gadget-ids, origined at FGAD      */
  625. X/* In the unlikely event this conflicts with any of your gadgets, */
  626. X/* change this equate to allow 16 contiguous unique ID's        */
  627. X
  628. X#define FGAD    0x76c0L
  629. X
  630. X#define FCHARS  32L     /* Number of chars allowed in file name */
  631. X
  632. X#define DIR_SIZ 50L     /* Number of chars in a dir name...     */
  633. X#define MAX_STR DIR_SIZ+2L
  634. X
  635. X#define DENTS   5L              /* Number of entries on screen   */
  636. X/* It's not as simple as changing 'DENTS'...      */
  637. X
  638. X#define DSIZE   FCHARS+1L       /* Size of a directory entry   */
  639. X
  640. X#define DBUFSIZ 3000L   /* Number of bytes to allocate for all ents */
  641. X
  642. X#define BCOL    1L      /* Background color     */
  643. X#define FCOL    2L      /* Foreground color     */
  644. X
  645. X#define RHGHT   120L
  646. X#define RWDTH   320L
  647. X
  648. X#define ZWDTH   270L
  649. X
  650. Xstatic char     ubuf[MAX_STR];          /* Undo buffer  */
  651. X
  652. Xstatic struct dirent { struct dirent *next; BOOL isfile; char dE[DSIZE+2]; };
  653. Xstatic struct dirent *FirstEntry;
  654. Xstatic struct dirent *NextEntry;
  655. X
  656. Xstatic struct dirhead { struct dirent *next; };
  657. Xstatic struct dirhead ListHead;
  658. X
  659. Xstatic long   curent,maxent;
  660. Xstatic BOOL   more;
  661. X
  662. Xstatic struct Window    *wRq = NL;              /* Requester window   */
  663. Xstatic struct RastPort  *wRp;
  664. X
  665. X/* Requester "Hailing" prompt */
  666. Xstatic struct IntuiText oTxt = {2,2,JAM1,10,11,NL, NL ,NL};
  667. X
  668. Xstatic struct IntuiText saydir = {0,1,JAM2,0,1,&MyFont,(UBYTE *)"(dir) ",NL};
  669. X
  670. Xstatic struct IntuiText rname[DENTS] = { /* File name list */
  671. X   {2,1,JAM2,48,1,NL,NL, NL},
  672. X   {2,1,JAM2,48,1,NL,NL, NL},
  673. X   {2,1,JAM2,48,1,NL,NL, NL},
  674. X   {2,1,JAM2,48,1,NL,NL, NL},
  675. X   {2,1,JAM2,48,1,NL,NL, NL} };
  676. X
  677. X/* Display for file name ... */
  678. X
  679. Xstatic SHORT oXY2[] = {-2,-2, RWDTH-78,-2, RWDTH-78,9, -2,9, -2,-2};
  680. Xstatic struct Border thebd = {0,0, 2,3,JAM1, 5,oXY2, NL};
  681. X
  682. Xstatic struct IntuiText otxt = {2,2,JAM1,-40,0,&MyFont,(UBYTE *)"file",NL};
  683. Xstatic struct StringInfo osx = { NL ,ubuf, NL,DSIZE,NL,NL,NL,NL,NL,NL,NL,NL,NL};
  684. Xstatic struct Gadget ogx = { NL, 60,RHGHT-35,RWDTH-80 ,10,     /* File name gadget */
  685. X   GADGHCOMP, RELVERIFY , STRGADGET,
  686. X   (APTR)&thebd,NL,&otxt,NL,(APTR)&osx, FGAD+11,NL };
  687. X
  688. Xstatic struct Gadget oga = { &ogx, 10,70, ZWDTH,10,   /* Gadgets For   */
  689. X   GADGHCOMP, RELVERIFY, BOOLGADGET,     /* Directory entries   */
  690. X   NL,NL, &rname[4] ,NL,NL, FGAD+10,NL };
  691. Xstatic struct Gadget og9 = {&oga, 10,60, ZWDTH,10,
  692. X   GADGHCOMP, RELVERIFY, BOOLGADGET,
  693. X   NL,NL, &rname[3] ,NL,NL, FGAD+9,NL };
  694. Xstruct Gadget og8 = {&og9, 10,50, ZWDTH,10,
  695. X   GADGHCOMP, RELVERIFY, BOOLGADGET,
  696. X   NL,NL, &rname[2] ,NL,NL, FGAD+8,NL };
  697. Xstatic struct Gadget og7 = {&og8, 10,40, ZWDTH,10,
  698. X   GADGHCOMP, RELVERIFY, BOOLGADGET,
  699. X   NL,NL, &rname[1] ,NL,NL, FGAD+7,NL };
  700. Xstatic struct Gadget og6 = {&og7, 10,30, ZWDTH,10,
  701. X   GADGHCOMP, RELVERIFY, BOOLGADGET,
  702. X   NL,NL, &rname[0] ,NL,NL, FGAD+6,NL };
  703. X
  704. X
  705. X/* Gadjets for requester  */
  706. X
  707. Xstatic SHORT oXY3[] = {0,0, 50,0, 50,9, 0,9, 0,0};
  708. Xstatic SHORT oXY4[] = {2,-2, 48,-2, 52,2, 52,7, 48,11, 2,11, -2,7, -2,2, 2,-2};
  709. Xstatic struct Border obd2 = {0,0, 2,3,JAM1, 9,oXY4, NL};
  710. Xstatic struct Border obd1 = {0,0, 3,2,JAM1, 5,oXY3, &obd2};  /* OTAY / CANCEL box */
  711. X
  712. Xstatic struct IntuiText ot1  = {0,0,JAM1,1,1,&MyFont,(UBYTE *)"  OK  ",NL};
  713. Xstatic struct IntuiText ot2  = {0,0,JAM1,1,1,&MyFont,(UBYTE *)"Cancel",NL};
  714. Xstatic struct IntuiText ot25 = {0,0,JAM1,1,1,&MyFont,(UBYTE *)"Device",NL};
  715. X
  716. Xstatic struct IntuiText dtxt = {2,2,JAM1,-60,0,NL,(UBYTE *)"drawer",NL};
  717. Xstatic struct StringInfo os5 = { NL ,ubuf, NL,DIR_SIZ,NL,NL,NL,NL,NL,NL,NL,NL,NL};
  718. Xstatic struct Gadget og5 = { &og6, RWDTH/2-80,19,190,10,     /* Directory */
  719. X   GADGHCOMP, RELVERIFY, STRGADGET,
  720. X   NL,NL,&dtxt,NL,(APTR)&os5, FGAD+5,NL };
  721. X
  722. Xstatic struct Image   cc_img;
  723. Xstatic struct PropInfo   cc_prop = {AUTOKNOB | FREEVERT, 0,0, 0,0x1000,0,0,0,0,0,0 };
  724. Xstatic struct Gadget og3 = { &og5,RWDTH-39,20,20,60,      /* Scroll Bar   */
  725. X    GADGHCOMP,GADGIMMEDIATE | FOLLOWMOUSE, PROPGADGET,
  726. X    (APTR)&cc_img,NL,NL,NL,(APTR)&cc_prop,FGAD+3,NL };
  727. X
  728. Xstatic struct Gadget og25 = { &og3, RWDTH-70,RHGHT-20, 50,10,  /* CANCEL */
  729. X   GADGHCOMP,  RELVERIFY, BOOLGADGET,
  730. X   (APTR)&obd1,NL, &ot2,NL,NL, FGAD+2,NL };
  731. X
  732. Xstatic struct Gadget og2 = { &og25, 136,RHGHT-20, 50,10,  /* DEVS */
  733. X   GADGHCOMP,  RELVERIFY, BOOLGADGET,
  734. X   (APTR)&obd1,NL, &ot25,NL,NL, FGAD+20,NL };
  735. X
  736. Xstatic struct Gadget og1 = { &og2, 20,RHGHT-20, 50,10,      /* OTAY   */
  737. X   GADGHCOMP,           /* Flags        */
  738. X   RELVERIFY,           /* Activation   */
  739. X   BOOLGADGET,
  740. X   (APTR)&obd1,NL,      /* GadgetRender, SelectRender   */
  741. X   &ot1,NL,NL,          /* IntuiText, MutualExclude,SpecialInfo   */
  742. X   FGAD+1,NL };         /* Gadget Id, UserData  */
  743. X
  744. X/* Open a requester "Window" */
  745. X
  746. Xstatic struct NewWindow NewFiles = {
  747. X   0, 0, RWDTH,RHGHT, BCOL,FCOL, NL, /* Fill in AFTER opening ... */
  748. X   SMART_REFRESH | ACTIVATE | RMBTRAP | WINDOWDRAG,
  749. X   &og1,NL,NL, NL,
  750. X   NL, RWDTH,RHGHT,RWDTH,RHGHT, CUSTOMSCREEN };
  751. X
  752. XIMPORT struct Library   *IntuitionBase;
  753. X
  754. X/***************************************************
  755. X*  get_fname(window,screen,hail,ddef,ddir);
  756. X*
  757. X*   Displays a window/requester that
  758. X* gets a file name for device,directory,default file, extension
  759. X*
  760. X*   Calling args:
  761. X* window:   Window making the request
  762. X* screen:   Screen, if NULL assummed workbench
  763. X* hail:   Text prompt at top of requester
  764. X* ddef:   Input default file-name. Has NO DIRECTORY OR EXTENSION.
  765. X* ddir:   Directory of file, may be null
  766. X
  767. X/* Set a file-requester with prompt 'hail'   */
  768. X
  769. Xchar *get_fname(cW,screen,hail,ddef,ddir)
  770. X   struct Window *cW;           /* Calling Window   */
  771. X   struct Screen *screen;       /* screen .... if null assumed workbench */
  772. X   UBYTE        *hail;          /* Hailing prompt   */
  773. X   char         *ddef;          /* Proable file-name   */
  774. X   char         *ddir;          /* Directory in which to search   */
  775. X   {
  776. X   FAST struct IntuiMessage *imes;   /* Wait for message in HERE   */
  777. X   FAST struct Gadget   *igad;   /* Get Gadjet Mumbo Jumbo   */
  778. X   FAST long    i,class;
  779. X   FAST TEXT    *pnam;
  780. X
  781. X   FAST char    *retval;
  782. X   FAST BOOL    dir_flag;
  783. X   FAST BOOL    keepon;
  784. X
  785. X   if ( ! (eW = cW) )   return(NL);
  786. X
  787. X   osx.Buffer = ddef;   /* Set default file name   */
  788. X   os5.Buffer = ddir;   /* Set default device name   */
  789. X
  790. X   for ( i=0; i<DENTS; i++)
  791. X      {
  792. X      rname[i].IText = "";
  793. X      rname[i].NextText = NL;
  794. X      };
  795. X
  796. X   NewFiles.Title = eW->Title;
  797. X   if ((dir_info = AllocMem((long)sizeof(struct FileInfoBlock),0L)) == NULL)
  798. X      return(NL);
  799. X
  800. X   if (screen)          /* User supplied a screen */
  801. X      {
  802. X      NewFiles.Type = CUSTOMSCREEN;
  803. X      NewFiles.Screen = screen;
  804. X      }
  805. X
  806. X   if ( ! (FirstEntry = (struct dirent *)AllocMem((long)DBUFSIZ,0L)) ||
  807. X        ! (wRq = (struct Window *)OpenWindow( &NewFiles )) )
  808. X      {
  809. X      if (!FirstEntry)
  810. X        notify("Can't Open first entry");
  811. X      if (!wRq)
  812. X        notify("Can't Open new window");
  813. X      if ( FirstEntry )   FreeMem(FirstEntry,(long)DBUFSIZ);
  814. X      /* notify("Can't Open Requester..."); */
  815. X      FreeMem(dir_info,(long)sizeof(struct FileInfoBlock));
  816. X      return(NL);
  817. X      }
  818. X   /* Set up directory, notify any errors...   */
  819. X   if ( pnam = (char *)dinit(ddir) )   notify(pnam);
  820. X
  821. X
  822. X   /* This optional line will activate a string gadget  */
  823. X   if ( IntuitionBase->lib_Version > 32 )
  824. X        {
  825. X        ActivateGadget(&ogx,wRq,0L);
  826. X        }
  827. X
  828. X   wRp = wRq->RPort;
  829. X
  830. X   wRq->UserPort = eW->UserPort;
  831. X   ModifyIDCMP(wRq,(long)(MOUSEBUTTONS | GADGETDOWN | GADGETUP | MOUSEMOVE));
  832. X
  833. X   SetAPen(wRp,1L);
  834. X   RectFill(wRp,4L,10L,(long)(RWDTH-5),(long)(RHGHT-4));
  835. X
  836. X   oTxt.IText = hail;   /* Set calling arg   */
  837. X   oTxt.LeftEdge = (RWDTH - IntuiTextLength(&oTxt)) >> 1L;
  838. X   PrintIText(wRp,&oTxt,0L,0L);
  839. X
  840. X   RefreshGadgets(&og1,wRq,(long)NL);
  841. X   for ( retval= NL, keepon=TRUE; keepon ; )
  842. X      {
  843. X      while ( ! (imes=(struct IntuiMessage *)GetMsg(wRq->UserPort)) )
  844. X      {
  845. X         if ( dir_flag )
  846. X            {
  847. X            i = (maxent-DENTS) * cc_prop.VertPot / MAXBODY;
  848. X            if ( i > (maxent-DENTS) )
  849. X            i = maxent-DENTS;
  850. X            if ( i <0 )   i = 0;
  851. X            curent = i;
  852. X            cxxx();
  853. X            dir_flag = FALSE;
  854. X            }
  855. X         if ( more )
  856. X            {
  857. X            if (pnam = (char *)dmore())   /* Continue to read the directory */
  858. X               notify(pnam);      /* Yucko error   */
  859. X            if ( maxent <= DENTS ) dir_flag = TRUE;
  860. X            }
  861. X         else    WaitPort(wRq->UserPort);
  862. X         }
  863. X      igad = (struct Gadget *)imes->IAddress;
  864. X      class = imes->Class;
  865. X      ReplyMsg(imes);
  866. X
  867. X      switch (class)
  868. X         {
  869. X         case MOUSEMOVE:      dir_flag = TRUE;   break;
  870. X
  871. X         case GADGETUP:
  872. X         case GADGETDOWN:
  873. X            switch ( i = igad->GadgetID)
  874. X            {
  875. X
  876. X            case FGAD+20:       /* Get device list                  */
  877. X               RemoveGadget(wRq,&og5);  /* File name gadget */
  878. X               ddir[0] = '\0';
  879. X               AddGadget(wRq,&og5,-1L);
  880. X               RefreshGadgets(&og5,wRq,(long)NL);
  881. X               getdisks();
  882. X               break;
  883. X
  884. X            case FGAD+6:
  885. X            case FGAD+7:
  886. X            case FGAD+8:
  887. X            case FGAD+9:
  888. X            case FGAD+10:       /* Replace file or directory name   */
  889. X               pnam = rname[i - (FGAD+6)].IText;
  890. X               if ( rname[igad->GadgetID - (FGAD+6)].NextText == NL )
  891. X                  {
  892. X                  RemoveGadget(wRq,&ogx);  /* File name gadget */
  893. X                  for (i=0; i<DSIZE; i++)      ddef[i] = *pnam++;
  894. X                  AddGadget(wRq,&ogx,-1L);
  895. X                  RefreshGadgets(&ogx,wRq,(long)NL);
  896. X                  break;
  897. X                  }
  898. X                  else
  899. X                  {
  900. X                  RemoveGadget(wRq,&og5);  /* Scroll bar */
  901. X                  rfnam(ddir,pnam);
  902. X                  AddGadget(wRq,&og5,-1L);
  903. X                  RefreshGadgets(&og5,wRq,(long)NL);
  904. X                  }
  905. X            case FGAD+5:
  906. X               if ( pnam = (char *)dinit(ddir) )
  907. X                  notify(pnam);
  908. X            case FGAD+3:
  909. X               dir_flag = TRUE;
  910. X               break;
  911. X
  912. X            case FGAD+11:      /* Name gadget, OTAY gadget   */
  913. X            case FGAD+1:
  914. X               retval = ddef;
  915. X            case FGAD+2:      /* Cancel gadget   */
  916. X               keepon = FALSE;
  917. X            }
  918. X         }
  919. X      }
  920. X
  921. X      FreeMem(FirstEntry,(long)DBUFSIZ );
  922. X      FreeMem(dir_info,(long)sizeof(struct FileInfoBlock));
  923. X      free_pdir();
  924. X
  925. X      CloseWindowSafely(wRq);
  926. X      return(retval);
  927. X   }
  928. X
  929. Xstatic free_pdir()
  930. X   {
  931. X   if ( pdir )
  932. X      {
  933. X      UnLock(pdir);
  934. X      pdir = NL;
  935. X      }
  936. X   }
  937. X
  938. X/*****************************************************************
  939. X* dvinit()
  940. X*   Initialize the fib for directory muck.  Null return
  941. X* is good, else return is a pointer to an error string      */
  942. X
  943. Xstatic char *dvinit(subdir)
  944. X   char *subdir;
  945. X   {
  946. X   more = FALSE;
  947. X   curent = maxent = 0;
  948. X
  949. X   NextEntry = FirstEntry;      /* Allocate from here   */
  950. X   ListHead.next = NL;          /* Clear the boogie     */
  951. X
  952. X   free_pdir();   /* Unlock any old lock... */
  953. X
  954. X   more = TRUE;
  955. X   }
  956. X
  957. X
  958. Xstatic char *dvmore(device)
  959. X  char *device;
  960. X   {
  961. X   FAST struct dirent   *p_D = NextEntry;
  962. X   FAST struct dirent   *ptr = (struct dirent *)&ListHead;
  963. X   FAST struct dirent   *plink;
  964. X
  965. X   FAST   TEXT   *p_mung;
  966. X
  967. X   FAST long    i;
  968. X
  969. X   if ( ! more )   return(NL);
  970. X
  971. X      if ( (ULONG)p_D >=
  972. X         ((ULONG)FirstEntry + (ULONG)DBUFSIZ - (ULONG)sizeof(struct dirent)) )
  973. X         {
  974. X         more = FALSE;
  975. X         return("Directory Truncated!");
  976. X         }
  977. X
  978. X
  979. X      /* Here you can add a file/directory filter   */
  980. X      /* filename text string is at &p_D->dE[0   */
  981. X      p_D->isfile = 0;
  982. X      p_mung = &p_D->dE[0];
  983. X
  984. X      for ( i=0; i<FCHARS; i++)
  985. X         if ( ! (*p_mung++ = *device++) )   break;
  986. X
  987. X      i = (long)p_mung;
  988. X      NextEntry = (struct dirent *)( (i+5L) & ~3L );
  989. X
  990. X      for ( i=maxent++; i>=0; i--)
  991. X         {
  992. X         if ( ! (plink = ptr->next)  )   break;
  993. X         if ( alpha_lower(p_D,plink) )   break;
  994. X         ptr = plink;
  995. X         }
  996. X
  997. X      p_D->next = plink;
  998. X      ptr->next = p_D;
  999. X
  1000. X      return(NL);
  1001. X}
  1002. X
  1003. X#include <exec/types.h>
  1004. X#include <exec/memory.h>
  1005. X#include <libraries/dos.h>
  1006. X#include <libraries/dosextens.h>
  1007. X#include <libraries/filehandler.h>
  1008. X
  1009. X#include <stdio.h>
  1010. X
  1011. X/* btoc() takes a pointer to a string in BCPL format and converts it to a
  1012. X * C string.
  1013. X */
  1014. Xvoid *btoc(bstring)
  1015. Xchar *bstring;
  1016. X{
  1017. X register UBYTE len,count,*cstring;
  1018. X
  1019. X cstring = (UBYTE *) bstring;
  1020. X len = cstring[0];
  1021. X for(count=0;count < len;count++)
  1022. X  cstring[count] = cstring[count+1];
  1023. X cstring[count] = '\0';
  1024. X}
  1025. X
  1026. X/* getdisks() will grab all disk device names in the system device list and
  1027. X *  append an exec node to a given list. The node being named in respect to the
  1028. X *  device.
  1029. X */
  1030. Xgetdisks()
  1031. X{
  1032. X extern struct DosLibrary         *DOSBase;
  1033. X struct RootNode                  *rnode;
  1034. X struct DosInfo                   *dinfo;
  1035. X register struct DeviceNode       *dnode;
  1036. X register struct Node             *adisk;
  1037. X char     *bname,name[32];
  1038. X
  1039. X rnode   = (struct RootNode *)  DOSBase->dl_Root;
  1040. X dinfo   = (struct DosInfo  *)  BADDR(rnode->rn_Info);
  1041. X
  1042. X dvinit();
  1043. X
  1044. X Forbid();
  1045. X for(dnode = (struct DeviceNode *) BADDR(dinfo->di_DevInfo);BADDR(dnode);
  1046. X        dnode = (struct DeviceNode *) BADDR(dnode->dn_Next))
  1047. X  {
  1048. X   if(!dnode->dn_Type && dnode->dn_Task && BADDR(dnode->dn_Name))
  1049. X
  1050. X/* if(dnode->dn_Task && BADDR(dnode->dn_Name))                      */
  1051. X    {
  1052. X     bname = (char *) BADDR(dnode->dn_Name);
  1053. X     movmem(bname,name,(ULONG)bname[0]+1L);
  1054. X     btoc(name); strcat(name,":");
  1055. X     dvmore(name);
  1056. X    }
  1057. X  }
  1058. X Permit();
  1059. X
  1060. X more = FALSE;
  1061. X cxxx();
  1062. X}
  1063. X
  1064. Xstatic char *dinit(subdir)
  1065. X   char *subdir;
  1066. X   {
  1067. X   more = FALSE;
  1068. X   curent = maxent = 0;
  1069. X
  1070. X   NextEntry = FirstEntry;      /* Allocate from here   */
  1071. X   ListHead.next = NL;          /* Clear the boogie     */
  1072. X
  1073. X   free_pdir();   /* Unlock any old lock... */
  1074. X
  1075. X   if (! (pdir=(struct FileLock *)Lock(subdir,(ULONG)ACCESS_READ)) )
  1076. X      return("Wrong Diskette?");
  1077. X   if ( ! Examine(pdir, dir_info) )   return("Wierd Disk Error");
  1078. X   if ( dir_info->fib_DirEntryType < 0L )   return("Bizzare Alert!!");
  1079. X
  1080. X   more = TRUE;
  1081. X   return(dmore());
  1082. X   }
  1083. X
  1084. X
  1085. Xstatic char *dmore()
  1086. X   {
  1087. X   FAST struct dirent   *p_D = NextEntry;
  1088. X   FAST struct dirent   *ptr = (struct dirent *)&ListHead;
  1089. X   FAST struct dirent   *plink;
  1090. X
  1091. X   FAST   TEXT   *p_mung;
  1092. X
  1093. X   FAST long    i;
  1094. X
  1095. X   if ( ! more )   return(NL);
  1096. X
  1097. X   if ( ExNext( pdir, dir_info ) )
  1098. X      {
  1099. X
  1100. X
  1101. X      if ( (ULONG)p_D >=
  1102. X         ((ULONG)FirstEntry + (ULONG)DBUFSIZ - (ULONG)sizeof(struct dirent)) )
  1103. X         {
  1104. X         more = FALSE;
  1105. X         return("Directory Truncated!");
  1106. X         }
  1107. X
  1108. X
  1109. X      /* Here you can add a file/directory filter   */
  1110. X      /* filename text string is at &p_D->dE[0   */
  1111. X      p_D->isfile = ( dir_info->fib_DirEntryType < 0L );
  1112. X      p_mung = &p_D->dE[0];
  1113. X
  1114. X      if ( IsInfo( dir_info->fib_FileName ) ) return(NL);
  1115. X
  1116. X      for ( i=0; i<FCHARS; i++)
  1117. X         if ( ! (*p_mung++ = dir_info->fib_FileName[i]) )   break;
  1118. X
  1119. X      i = (long)p_mung;
  1120. X      NextEntry = (struct dirent *)( (i+5L) & ~3L );
  1121. X
  1122. X      for ( i=maxent++; i>=0; i--)
  1123. X         {
  1124. X         if ( ! (plink = ptr->next)  )   break;
  1125. X         if ( alpha_lower(p_D,plink) )   break;
  1126. X         ptr = plink;
  1127. X         }
  1128. X      p_D->next = plink;
  1129. X      ptr->next = p_D;
  1130. X
  1131. X      return(NL);
  1132. X      }
  1133. X   else return ( IoErr() == ERROR_NO_MORE_ENTRIES) ?
  1134. X       (char *)(more = (long)NL) : "Error Reading Directory!!!";
  1135. X   }
  1136. X
  1137. XIsInfo( str )
  1138. X  char *str;
  1139. X{
  1140. X  int len;
  1141. X
  1142. X  len = strlen(str);
  1143. X
  1144. X  if (len > 5) {
  1145. X    return( strcmp( str + len - 5, ".info" ) == 0 );
  1146. X  }
  1147. X
  1148. X  return( 0 );
  1149. X}
  1150. X
  1151. X/* dedicated alphabetizing function for dmore()   */
  1152. X
  1153. Xstatic alpha_lower(snew,sold)
  1154. X   struct dirent *snew,*sold;
  1155. X   {
  1156. X   FAST struct dirent *pnew = snew;
  1157. X   FAST TEXT *ps1,*ps2, c,d;
  1158. X
  1159. X   if ( pnew->isfile == sold->isfile)
  1160. X      {
  1161. X      ps1 = &pnew->dE[0];
  1162. X      ps2 = &sold->dE[0];
  1163. X      while ( (c=*ps1++) )
  1164. X         {
  1165. X         if ( c > (d=*ps2++) )   return(FALSE);
  1166. X         else if ( c < d )      break;
  1167. X         }
  1168. X      return(TRUE);
  1169. X      }
  1170. X   return(pnew->isfile);
  1171. X   }
  1172. X
  1173. X
  1174. X
  1175. X/* Display directory stuff   */
  1176. X
  1177. Xstatic cxxx()
  1178. X   {
  1179. X   FAST long   i,new;
  1180. X   FAST long   x,y;
  1181. X   FAST struct dirent *ohboy = (struct dirent *)&ListHead;
  1182. X
  1183. X   new = curent;
  1184. X   for ( i=0; i<new; i++)   ohboy = ohboy->next;
  1185. X
  1186. X   y = 20L;
  1187. X   for (i=0; i<DENTS; i++)
  1188. X      {
  1189. X      y += (x=10);
  1190. X      rname[i].NextText = NL;
  1191. X      rname[i].IText = "";
  1192. X      rname[i].LeftEdge = 0;
  1193. X      if ( (new+i) < maxent )
  1194. X         {
  1195. X         ohboy = ohboy->next;
  1196. X         rname[i].IText = &ohboy->dE[0];
  1197. X         if ( ohboy->isfile )   PrintIText(wRp,&rname[i],10L,y);
  1198. X         else
  1199. X            {
  1200. X            rname[i].LeftEdge = 48;
  1201. X            PrintIText(wRp,&saydir,10L,y);
  1202. X            PrintIText(wRp,&rname[i],10L,y);
  1203. X            rname[i].NextText = &saydir;
  1204. X            }
  1205. X         x = wRp->cp_x;
  1206. X         }
  1207. X      if ( x < ZWDTH+10 )   RectFill(wRp,x,y,(long)(ZWDTH+10),(long)(y+8L));
  1208. X      }
  1209. X   }
  1210. X
  1211. X
  1212. X/**************************************************
  1213. X* rfnam()
  1214. X*   Combines dir, plus name into dir   */
  1215. X
  1216. Xstatic rfnam(dir,fil_nam)
  1217. X   char *dir,*fil_nam;
  1218. X   {
  1219. X   FAST char   *pdst = dir;
  1220. X   FAST char   *psrc = fil_nam;
  1221. X   FAST char   c = ':';
  1222. X
  1223. X   while ( *pdst )
  1224. X      c = *pdst++;
  1225. X   if ( c != ':')   *pdst++ = '/';
  1226. X
  1227. X   while ( *pdst++ = *psrc++ )
  1228. X      ;
  1229. X   }
  1230. X
  1231. Xstatic struct IntuiText b_txt = {0,1,JAM2, 5,20,NL,NL,    NL};
  1232. Xstatic struct IntuiText p_txt = {0,1,JAM2, 5,3,NL,"OK", NL};
  1233. X
  1234. X/****************************************************************/
  1235. X/* notify(txt)                     */
  1236. X/*   Prompts for Yes/No response            */
  1237. X
  1238. Xstatic notify(txt)
  1239. X   char *txt;
  1240. X   {
  1241. X   b_txt.IText = txt;
  1242. X   AutoRequest(wRq,&b_txt,0L,&p_txt,0L,0L,
  1243. X      (long)(IntuiTextLength(&b_txt)+50L),70L);
  1244. X   }
  1245. SHAR_EOF
  1246. echo "extracting getfile.h"
  1247. sed 's/^X//' << \SHAR_EOF > getfile.h
  1248. X/***************************************************
  1249. X*  get_fname(window,screen,hail,ddef,ddir);
  1250. X*
  1251. X*   Displays a window/requester that
  1252. X* gets a file name for device,directory,default file, extension
  1253. X*
  1254. X*   Calling args:
  1255. X* window:   Window making the request
  1256. X* screen:   Screen, if NULL assummed workbench
  1257. X* hail:   Text prompt at top of requester
  1258. X* ddef:   Input default file-name. Has NO DIRECTORY OR EXTENSION.
  1259. X* ddir:   Directory of file, may be null
  1260. X*
  1261. X*  The basic call is:
  1262. X*
  1263. X*   getfile(Window,Screen,Hailing_string,file_name,directory_name);
  1264. X*
  1265. X* Where:
  1266. X*   Window is a pointer to your window
  1267. X*   Screen is a pointer to your screen ... or (long)NULL if workbench
  1268. X*   Hailing_string is a prompt displayed in the requester
  1269. X*   file_name is a text array which will be altered by getfile,
  1270. X*   it returns the file name.
  1271. X*   directory_name is a text array altered by getfile, it
  1272. X*   is the directory.
  1273. X*
  1274. X*   The return value is either a pointer to your buffer, file_name,
  1275. X*   or NULL if the user selected CANCEL.
  1276. X*
  1277. X*   You must reserve two text areas for file and directory like so:
  1278. X*
  1279. X* #define FNAME_SIZE 33
  1280. X* TEXT   file_name[FNAME_SIZE + 1];
  1281. X* TEXT   dir_name[FNAME_SIZE + 2]
  1282. X**********************************************************************/
  1283. X
  1284. X#ifndef GET_FNAME
  1285. X
  1286. X#define GET_FNAME
  1287. X
  1288. X#define FNAME_SIZE 33
  1289. X
  1290. Xextern char *get_fname();
  1291. X
  1292. X#endif
  1293. X
  1294. SHAR_EOF
  1295. echo "extracting getint.c"
  1296. sed 's/^X//' << \SHAR_EOF > getint.c
  1297. X/*
  1298. X * MandelVroom 2.0
  1299. X *
  1300. X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  1301. X *
  1302. X * All rights reserved.
  1303. X *
  1304. X * Permission is hereby granted to distribute this program's source
  1305. X * executable, and documentation for non-comercial purposes, so long as the
  1306. X * copyright notices are not removed from the sources, executable or
  1307. X * documentation.  This program may not be distributed for a profit without
  1308. X * the express written consent of the author Kevin L. Clague.
  1309. X *
  1310. X * This program is not in the public domain.
  1311. X *
  1312. X * Fred Fish is expressly granted permission to distribute this program's
  1313. X * source and executable as part of the "Fred Fish freely redistributable
  1314. X * Amiga software library."
  1315. X *
  1316. X * Permission is expressly granted for this program and it's source to be
  1317. X * distributed as part of the Amicus Amiga software disks, and the
  1318. X * First Amiga User Group's Hot Mix disks.
  1319. X *
  1320. X * contents: this file implements a requester like window to get an integer
  1321. X * value from the user.
  1322. X */
  1323. X
  1324. X#include "mandp.h"
  1325. X
  1326. Xstruct Window *GetIWind;
  1327. X
  1328. X#define GIWIDTH  190
  1329. X#define GIHEIGHT 50
  1330. X
  1331. Xstatic
  1332. Xstruct NewWindow NewGetI = {
  1333. X   (320-GIWIDTH)/2,(200-GIHEIGHT)/2, /* start position           */
  1334. X   GIWIDTH,GIHEIGHT,                 /* width, height            */
  1335. X   (UBYTE) 0, (UBYTE) 1,     /* detail pen, block pen    */
  1336. X   NULL,                     /* IDCMP flags */
  1337. X   SMART_REFRESH,            /* MandWind flags */
  1338. X   (struct Gadget *) NULL,   /* first gadget             */
  1339. X   (struct Image *) NULL,    /* user checkmark           */
  1340. X   (UBYTE *) NULL,           /* window title             */
  1341. X   (struct Screen *) NULL,   /* pointer to screen        */
  1342. X   (struct BitMap *) NULL,   /* pointer to superbitmap   */
  1343. X   80,80,80,80,              /* sizing                   */
  1344. X   CUSTOMSCREEN              /* type of screen           */
  1345. X};
  1346. X#define GETINOTDONE 0
  1347. X#define GETIDONEOK  1
  1348. X#define GETICANCEL  2
  1349. X
  1350. XUBYTE IDone;
  1351. X
  1352. Xchar *IString;
  1353. X
  1354. X/*
  1355. X * Allocate all the gadgets and things for the get int window
  1356. X */
  1357. Xstruct Gadget *MakeGetInt( Title, IVal )
  1358. X  char *Title;
  1359. X  LONG IVal;
  1360. X{
  1361. X
  1362. X  register struct Gadget *NextGadget;
  1363. X  register SHORT *Height;
  1364. X  register struct StringInfo *StringInfo;
  1365. X  register struct Gadget *FirstGadget, *OldGadget;
  1366. X
  1367. X  char string[80];
  1368. X
  1369. X  extern struct Gadget *MakeBool();
  1370. X  extern struct Gadget *MakeString();
  1371. X  extern struct IntuiText *MakeIntui();
  1372. X
  1373. X  LONG i;
  1374. X
  1375. X#define GETICANID  0xffff
  1376. X#define GETIOKID   0xfffe
  1377. X#define GETISTRID  0xfffd
  1378. X
  1379. X  FirstGadget = MakeBool(127, 32, 54, 12, 1, GETICANID, NULL);
  1380. X  if (FirstGadget == NULL) {
  1381. X    goto error;
  1382. X  }
  1383. X  FirstGadget->GadgetText = ShadowIntui("Cancel", 4, 3);
  1384. X
  1385. X  if ( FirstGadget->GadgetText == NULL ) goto error;
  1386. X
  1387. X  NextGadget = OldGadget = MakeBool(6, 32, 54, 12, 1, GETIOKID, NULL);
  1388. X
  1389. X  if (NextGadget == NULL) goto error;
  1390. X
  1391. X  NextGadget->GadgetText = ShadowIntui("  OK", 4, 3);
  1392. X
  1393. X  if ( NextGadget->GadgetText == NULL ) goto error;
  1394. X
  1395. X  FirstGadget->NextGadget = NextGadget;
  1396. X
  1397. X  sprintf( string,"%d",IVal );
  1398. X  NextGadget = MakeString( 55, 16, 10, GETISTRID, string );
  1399. X
  1400. X  if (NextGadget == NULL) goto error;
  1401. X
  1402. X  NextGadget->GadgetText = ShadowIntui(Title,-10,-11);
  1403. X
  1404. X  if ( NextGadget->GadgetText == NULL ) goto error;
  1405. X
  1406. X/*i = IntuiTextLength(NextGadget->GadgetText);
  1407. X  NextGadget->GadgetText->LeftEdge = (GIWIDTH-i)/2;  */
  1408. X
  1409. X  OldGadget->NextGadget = NextGadget;
  1410. X
  1411. X  StringInfo = (struct StringInfo *) NextGadget->SpecialInfo;
  1412. X  IString = (char *) StringInfo->Buffer;
  1413. X
  1414. X  return( FirstGadget );
  1415. X
  1416. Xerror:
  1417. X  FreeGadgets(FirstGadget);
  1418. X  return((struct Gadget *) NULL);
  1419. X
  1420. X} /* MakeGetInt */
  1421. X
  1422. Xstatic struct Gadget *GetGadgets;
  1423. X
  1424. X/*
  1425. X * Get an Integr from the user
  1426. X */
  1427. XGetInt( Title, IVal)
  1428. X  char *Title;
  1429. X  LONG *IVal;
  1430. X{
  1431. X  register struct Gadget *Gadgets;
  1432. X  register struct Window *Window;
  1433. X  register LONG   i;
  1434. X  register struct RastPort *Rp;
  1435. X
  1436. X  struct Window *OpenMyWind();
  1437. X
  1438. X  IDone = GETINOTDONE;
  1439. X
  1440. X  if (GetIWind == NULL ) {
  1441. X
  1442. X    Gadgets = MakeGetInt( Title, *IVal );
  1443. X
  1444. X    if (Gadgets == NULL) {
  1445. X      DispErrMsg("Panic. No Gadgets\n",0);
  1446. X      return( 0 );
  1447. X    } else {
  1448. X      Window = OpenMyWind( &NewGetI, screen, NULL, GIWIDTH, GIHEIGHT);
  1449. X
  1450. X      GetIWind = Window;
  1451. X
  1452. X      if (Window) {
  1453. X
  1454. X        Rp = Window->RPort;
  1455. X
  1456. X        CurWind = Window;
  1457. X
  1458. X        SetAPen( Rp, NORMALPEN );
  1459. X        RectFill( Rp,0,0,Window->Width,Window->Height);
  1460. X
  1461. X        GetGadgets = Gadgets;
  1462. X
  1463. X        AddGList( Window, Gadgets, -1, -1);
  1464. X
  1465. X        RefreshGadgets( Gadgets, Window, NULL );
  1466. X
  1467. X        SetAPen( Rp, HIGHLIGHTPEN );
  1468. X        Move( Rp, 0,               Window->Height-1 );
  1469. X        Draw( Rp, 0,               0 );
  1470. X        Draw( Rp, Window->Width-1, 0 );
  1471. X
  1472. X        SetAPen( Rp, SHADOWPEN );
  1473. X        Draw( Rp, Window->Width-1, Window->Height-1 );
  1474. X        Draw( Rp, 0,               Window->Height-1 );
  1475. X
  1476. X        DoIGet();
  1477. X        if (IDone == GETIDONEOK) {
  1478. X          sscanf( IString,"%d", IVal);
  1479. X        }
  1480. X        CloseGetIWind();
  1481. X      } else {
  1482. X        return( 0 );
  1483. X      }
  1484. X    }
  1485. X  }
  1486. X  return( IDone == GETIDONEOK );
  1487. X} /* OpenGetIWind */
  1488. X
  1489. X/*
  1490. X * Close the get integer window
  1491. X */
  1492. XCloseGetIWind()
  1493. X{
  1494. X  if (GetIWind != NULL) {
  1495. X    CloseMyWind( GetIWind, GetGadgets );
  1496. X    GetIWind = NULL;
  1497. X  }
  1498. X} /* CloseGetIWind */
  1499. X
  1500. X/*
  1501. X * Wait and process a message
  1502. X */
  1503. XDoIGet()
  1504. X{
  1505. X  while (IDone == GETINOTDONE) {
  1506. X
  1507. X    Wait( 1 << BackWind->UserPort->mp_SigBit );
  1508. X
  1509. X    DoIMsg();
  1510. X  }
  1511. X}
  1512. X
  1513. X/*
  1514. X * if there is a message, process it
  1515. X */
  1516. XDoIMsg()
  1517. X{
  1518. X  register ULONG Class;
  1519. X  register struct IntuiMessage *message;
  1520. X  register struct Gadget *gadget;
  1521. X
  1522. X  while (message = (struct IntuiMessage *) GetMsg( BackWind->UserPort)) {
  1523. X
  1524. X    Class = message->Class;
  1525. X    gadget = (struct Gadget *) message->IAddress;
  1526. X
  1527. X    /* got a message */
  1528. X
  1529. X    ReplyMsg(message);
  1530. X
  1531. X    CheckButtons( gadget, Class );
  1532. X  }
  1533. X} /* DoIMsg */
  1534. X
  1535. XCheckButtons( gadget, class )
  1536. X  struct Gadget *gadget;
  1537. X  ULONG class;
  1538. X{
  1539. X  if (class == GADGETDOWN) {
  1540. X
  1541. X    switch( gadget->GadgetID ) {
  1542. X
  1543. X      case GETICANID:
  1544. X           IDone = GETICANCEL;
  1545. X           break;
  1546. X
  1547. X      case GETIOKID:
  1548. X           IDone = GETIDONEOK;
  1549. X           break;
  1550. X    }
  1551. X  }
  1552. X} /* CheckButtons */
  1553. SHAR_EOF
  1554. echo "extracting help.c"
  1555. sed 's/^X//' << \SHAR_EOF > help.c
  1556. X/*
  1557. X * MandelVroom 2.0
  1558. X *
  1559. X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  1560. X *
  1561. X * All rights reserved.
  1562. X *
  1563. X * Permission is hereby granted to distribute this program's source
  1564. X * executable, and documentation for non-comercial purposes, so long as the
  1565. X * copyright notices are not removed from the sources, executable or
  1566. X * documentation.  This program may not be distributed for a profit without
  1567. X * the express written consent of the author Kevin L. Clague.
  1568. X *
  1569. X * This program is not in the public domain.
  1570. X *
  1571. X * Fred Fish is expressly granted permission to distribute this program's
  1572. X * source and executable as part of the "Fred Fish freely redistributable
  1573. X * Amiga software library."
  1574. X *
  1575. X * Permission is expressly granted for this program and it's source to be
  1576. X * distributed as part of the Amicus Amiga software disks, and the
  1577. X * First Amiga User Group's Hot Mix disks.
  1578. X *
  1579. X * contents: this file decodes gadget or menu types to determine what help
  1580. X * file should be displayed in the help window.
  1581. X */
  1582. X
  1583. X#include "mandp.h"
  1584. X
  1585. Xstatic char *HelpFile;
  1586. X
  1587. XScrollHelpCmd(Msg)
  1588. X  struct IntuiMessage *Msg;
  1589. X{
  1590. X  struct Window *window;
  1591. X  struct Gadget *gadget;
  1592. X
  1593. X  window = Msg->IDCMPWindow;
  1594. X  gadget = (struct Gadget *) Msg->IAddress;
  1595. X
  1596. X  switch (Msg->Class) {
  1597. X
  1598. X    case GADGETDOWN:
  1599. X         ModifyIDCMP(window, window->IDCMPFlags | MOUSEMOVE);
  1600. X         State = SCROLLHELPSTATE;
  1601. X         break;
  1602. X
  1603. X    case MOUSEMOVE:
  1604. X         Page_File(HELPSCROLL);
  1605. X         break;
  1606. X
  1607. X    case GADGETUP:
  1608. X         if (gadget->GadgetID == HELPSCROLL) {
  1609. X           ModifyIDCMP(window, window->IDCMPFlags & ~MOUSEMOVE);
  1610. X         }
  1611. X         Page_File(HELPSCROLL);
  1612. X         break;
  1613. X  }
  1614. X}
  1615. X
  1616. XHelpMenuCmd( Msg )
  1617. X  struct IntuiMessage *Msg;
  1618. X{
  1619. X  register USHORT code;
  1620. X
  1621. X  code = Msg->Code;
  1622. X
  1623. X  HelpFile = NULL;
  1624. X
  1625. X  if (code == MENUNULL)
  1626. X    return;
  1627. X
  1628. X  switch ( MENUNUM( code ) ) {
  1629. X
  1630. X    case PROJECTMENU:
  1631. X         HelpProjectMenu(code);
  1632. X         break;
  1633. X
  1634. X    case DISPLAYMENU:
  1635. X         HelpDisplayMenu(code);
  1636. X         break;
  1637. X
  1638. X    case CALCULATEMENU:
  1639. X         HelpCalculateMenu(code);
  1640. X         break;
  1641. X
  1642. X    case SPECIALMENU:
  1643. X         HelpSpecialMenu(code);
  1644. X         break;
  1645. X  }
  1646. X
  1647. X  if (HelpFile == NULL)
  1648. X    DispErrMsg("No Help for that object",0);
  1649. X  else
  1650. X    ShowHelp("Mandelbrot:Help/",HelpFile);
  1651. X
  1652. X}
  1653. X
  1654. X/*
  1655. X * Decide what to do for Project menu's Items
  1656. X */
  1657. XHelpProjectMenu(code)
  1658. X  USHORT code;
  1659. X{
  1660. X  switch (ITEMNUM(code)) {
  1661. X
  1662. X    case NEWITEM:
  1663. X
  1664. X         switch( SUBNUM(code) ) {
  1665. X           case 0:
  1666. X                HelpFile = "NewMand";
  1667. X                break;
  1668. X
  1669. X           case 1:
  1670. X                HelpFile = "NewJulia";
  1671. X                break;
  1672. X         }
  1673. X         break;
  1674. X
  1675. X    case HELPITEM:
  1676. X         HelpFile = "Help";
  1677. X         break;
  1678. X
  1679. X    case CURITEM:
  1680. X         HelpFile = "Current";
  1681. X         break;
  1682. X
  1683. X    case CLOSEPROJ:
  1684. X         HelpFile = "CloseProj";
  1685. X         break;
  1686. X
  1687. X    case SAVEPROJ:
  1688. X    case LOADITEM:
  1689. X         HelpFile = "Load.Save";
  1690. X         break;
  1691. X
  1692. X    case SAVEILBM:
  1693. X         HelpFile = "SaveILBM";
  1694. X         break;
  1695. X
  1696. X    case CANCELITEM:
  1697. X         HelpFile = "CancelCmd";
  1698. X         break;
  1699. X
  1700. X    case QUITITEM:
  1701. X         HelpFile = "Quit";
  1702. X         break;
  1703. X    }
  1704. X} /* HelpProjectMenu */
  1705. X
  1706. X/*
  1707. X * Decide what to do for Edit menu's Items
  1708. X */
  1709. XHelpDisplayMenu(code)
  1710. X  USHORT code;
  1711. X{
  1712. X  switch (ITEMNUM(code)) {
  1713. X
  1714. X    case COLORITEM:
  1715. X         HelpFile = "ColorPalette";
  1716. X         break;
  1717. X
  1718. X    case CYCLEITEM:
  1719. X         HelpFile = "CycleControl";
  1720. X         break;
  1721. X
  1722. X    case CONTOURITEM:
  1723. X         HelpFile = "ContourGen";
  1724. X         break;
  1725. X
  1726. X    case AUTOCNTRITEM:
  1727. X         HelpFile = "AutoContour";
  1728. X         break;
  1729. X
  1730. X    case HISTOGRAMITEM:
  1731. X         HelpFile = "Histogram";
  1732. X         break;
  1733. X
  1734. X    case DEPTHITEM:
  1735. X         InitDepthSubs();
  1736. X         HelpFile = "NumColors";
  1737. X         break;
  1738. X
  1739. X    case VIEWMODEITEM:
  1740. X         InitViewModesSubs();
  1741. X         HelpFile = "ScreenType";
  1742. X         break;
  1743. X
  1744. X    case SCREENITEM:
  1745. X         InitSizeSubs();
  1746. X         HelpFile = "ScreenSize";
  1747. X         break;
  1748. X
  1749. X    case BORDERITEM:
  1750. X         InitBorderSubs();
  1751. X         HelpFile = "Border";
  1752. X         break;
  1753. X    }
  1754. X} /* HelpDisplayMenu */
  1755. X
  1756. X/*
  1757. X * Decide what to do for Special Menu's Items
  1758. X */
  1759. XHelpCalculateMenu(code)
  1760. X  USHORT code;
  1761. X{
  1762. X  switch (ITEMNUM(code)) {
  1763. X
  1764. X    case ZOOMITEM:
  1765. X
  1766. X         switch(SUBNUM(code)) {
  1767. X           case ZOOMIN:
  1768. X                HelpFile = "ZoomIn";
  1769. X                break;
  1770. X           case ZOOMOUT:
  1771. X                HelpFile = "ZoomOut";
  1772. X                break;
  1773. X           case ZOOMOFF:
  1774. X                HelpFile = "ZoomClose";
  1775. X                break;
  1776. X           case ZOOMJULIA:
  1777. X                HelpFile = "ZoomJulia";
  1778. X                break;
  1779. X         }
  1780. X         break;
  1781. X
  1782. X    case SCROLLITEM:
  1783. X         HelpFile = "Pan";
  1784. X         break;
  1785. X
  1786. X    case LENSITEM:
  1787. X         InitLensSubs();
  1788. X         HelpFile = "Lens";
  1789. X         break;
  1790. X
  1791. X    case GENERATEITEM:
  1792. X         HelpFile = "Generate";
  1793. X         break;
  1794. X
  1795. X    case GENERATORITEM:   /* generator type */
  1796. X         InitGenSubs();
  1797. X         HelpFile = "Generator";
  1798. X         break;
  1799. X
  1800. X    case STATSITEM:
  1801. X         HelpFile = "Statistics";
  1802. X         break;
  1803. X
  1804. X    case COUNTITEM:
  1805. X         HelpFile = "MaxIteration";
  1806. X         break;
  1807. X  }
  1808. X} /* HelpCalcualteMenu */
  1809. X
  1810. X/*
  1811. X * Decide what to do for Special Menu's Items
  1812. X */
  1813. XHelpSpecialMenu(code)
  1814. X  USHORT code;
  1815. X{
  1816. X  switch (ITEMNUM(code)) {
  1817. X
  1818. X    case PRESETITEM:
  1819. X         HelpFile = "Presets";
  1820. X         break;
  1821. X
  1822. X    case ORBITITEM:
  1823. X         HelpFile = "Orbit";
  1824. X         break;
  1825. X
  1826. X    case ORBITMATHITEM:
  1827. X         HelpFile = "MathOrbit";
  1828. X         break;
  1829. X
  1830. X    case MAXORBITEM:
  1831. X         HelpFile = "MaxOrbit";
  1832. X         break;
  1833. X  }
  1834. X} /* HelpCalculateMenu */
  1835. X
  1836. X/*
  1837. X * Perform functions for Gadget down messages
  1838. X */
  1839. XHelpGadgetCmd(Msg)
  1840. X  struct IntuiMessage *Msg;
  1841. X{
  1842. X  struct Gadget *gadget;
  1843. X
  1844. X  gadget = (struct Gadget *) Msg->IAddress;
  1845. X
  1846. X  HelpFile = NULL;
  1847. X
  1848. X  switch (gadget->GadgetID >> WINDTYPEBITS & WINDMASK) {
  1849. X
  1850. X  case PALTYPE:
  1851. X       HelpPalGadget(gadget);
  1852. X       break;
  1853. X
  1854. X  case CONTYPE:
  1855. X       HelpContGadget(gadget);
  1856. X       break;
  1857. X
  1858. X  case PICTTYPE:
  1859. X       HelpPictGadget(gadget);
  1860. X       break;
  1861. X
  1862. X  case CYCTYPE:
  1863. X       HelpCycGadget(gadget);
  1864. X       break;
  1865. X
  1866. X  case ORBTTYPE:
  1867. X       HelpFile = "Orbit";
  1868. X       break;
  1869. X  }
  1870. X
  1871. X  if (HelpFile != NULL)
  1872. X    ShowHelp("Mandelbrot:Help/",HelpFile);
  1873. X  else
  1874. X    DispErrMsg("No Help for that object",0);
  1875. X}
  1876. X
  1877. X/*
  1878. X * Interpret the gadgets and do the right thing
  1879. X */
  1880. XHelpPalGadget(gadget)
  1881. X  register struct Gadget *gadget;
  1882. X{
  1883. X  switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
  1884. X
  1885. X  case PALPENS:
  1886. X       HelpFile = "PalPens";
  1887. X       break;
  1888. X
  1889. X  case PALCNTLS:
  1890. X       HelpPalCntl(gadget);
  1891. X       break;
  1892. X
  1893. X  case PALPOTS:
  1894. X       HelpFile = "PalPots";
  1895. X       break;
  1896. X  }
  1897. X} /* HelpPalGadget */
  1898. X
  1899. X/*
  1900. X * We got a color palette command gadget
  1901. X */
  1902. XHelpPalCntl(gadget)
  1903. X  register struct Gadget *gadget;
  1904. X{
  1905. X  switch (gadget->GadgetID) {
  1906. X
  1907. X  case PALCOPY:
  1908. X       HelpFile = "PalCopy";
  1909. X       break;
  1910. X
  1911. X  case PALRANGE:
  1912. X       HelpFile = "PalRange";
  1913. X       break;
  1914. X
  1915. X  case PALEXCG:
  1916. X       HelpFile = "PalExchg";
  1917. X       break;
  1918. X  }
  1919. X} /* HelpPalCntl */
  1920. X
  1921. XHelpPictGadget(gadget)
  1922. X  register struct Gadget *gadget;
  1923. X{
  1924. X  switch (gadget->GadgetID) {
  1925. X
  1926. X    case PICTCUR:
  1927. X         HelpFile = "PictCur";
  1928. X         break;
  1929. X
  1930. X    case PICTGEN:
  1931. X         HelpFile = "Generate";
  1932. X         break;
  1933. X
  1934. X    case PICTIN:
  1935. X         HelpFile = "ZoomIn";
  1936. X         break;
  1937. X
  1938. X    case PICTOUT:
  1939. X         HelpFile = "ZoomOut";
  1940. X         break;
  1941. X
  1942. X    case PICTJULIA:
  1943. X         HelpFile = "ZoomJulia";
  1944. X         break;
  1945. X  }
  1946. X}
  1947. X
  1948. X/*
  1949. X * Figure out what to do for this contour gadget
  1950. X */
  1951. XHelpContGadget(gadget)
  1952. X  struct Gadget *gadget;
  1953. X{
  1954. X  switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
  1955. X
  1956. X    case CONTCNTLS:
  1957. X         switch (gadget->GadgetID) {
  1958. X           case CONTRECOL:
  1959. X                HelpFile = "Paint";
  1960. X                break;
  1961. X
  1962. X           case CONTSET:
  1963. X                HelpFile = "ContSet";
  1964. X                break;
  1965. X
  1966. X           case CONTSMTH:
  1967. X                HelpFile = "ContSmooth";
  1968. X                break;
  1969. X
  1970. X           case CONTCUT:
  1971. X                HelpFile = "ContCut";
  1972. X                break;
  1973. X
  1974. X           case CONTCOPY:
  1975. X                HelpFile = "ContCopy";
  1976. X                break;
  1977. X
  1978. X           case CONTPASTE:
  1979. X                HelpFile = "ContPaste";
  1980. X                break;
  1981. X
  1982. X           case CONTLAST:
  1983. X                HelpFile = "ContLast";
  1984. X                break;
  1985. X
  1986. X           case CONTCEIL:
  1987. X                HelpFile = "ContCeil";
  1988. X                break;
  1989. X         }
  1990. X         break;
  1991. X
  1992. X    case CONTSELS:
  1993. X         HelpFile = "ContPens";
  1994. X         break;
  1995. X
  1996. X    case CONTPOTS:
  1997. X         HelpFile = "ContPots";
  1998. X         break;
  1999. X  }
  2000. X}
  2001. X
  2002. X/*
  2003. X * Figure out what to do for this color cycle gadget
  2004. X */
  2005. XHelpCycGadget(gadget)
  2006. X  struct Gadget *gadget;
  2007. X{
  2008. X  switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
  2009. X
  2010. X    case CYCCNTLS:
  2011. X         switch (gadget->GadgetID) {
  2012. X           case CYCRANGE:
  2013. X                HelpFile = "CycRange";
  2014. X                break;
  2015. X
  2016. X           case CYCDIR:
  2017. X                HelpFile = "CycDir";
  2018. X                break;
  2019. X
  2020. X           case CYCSPEED:
  2021. X                HelpFile = "CycSpeed";
  2022. X                break;
  2023. X
  2024. X           case CYCON:
  2025. X                HelpFile = "CycOn";
  2026. X                break;
  2027. X         }
  2028. X         break;
  2029. X
  2030. X    case CYCRNUMS:
  2031. X         HelpFile = "CycRNums";
  2032. X         break;
  2033. X  }
  2034. X}
  2035. X
  2036. X
  2037. X
  2038. SHAR_EOF
  2039. echo "extracting hist.c"
  2040. sed 's/^X//' << \SHAR_EOF > hist.c
  2041. X/*
  2042. X * MandelVroom 2.0
  2043. X *
  2044. X * (c) Copyright 1987,1989  Kevin L. Clague, San Jose, CA
  2045. X *
  2046. X * All rights reserved.
  2047. X *
  2048. X * Permission is hereby granted to distribute this program's source
  2049. X * executable, and documentation for non-comercial purposes, so long as the
  2050. X * copyright notices are not removed from the sources, executable or
  2051. X * documentation.  This program may not be distributed for a profit without
  2052. X * the express written consent of the author Kevin L. Clague.
  2053. X *
  2054. X * This program is not in the public domain.
  2055. X *
  2056. X * Fred Fish is expressly granted permission to distribute this program's
  2057. X * source and executable as part of the "Fred Fish freely redistributable
  2058. X * Amiga software library."
  2059. X *
  2060. X * Permission is expressly granted for this program and it's source to be
  2061. X * distributed as part of the Amicus Amiga software disks, and the
  2062. X * First Amiga User Group's Hot Mix disks.
  2063. X *
  2064. X * contents: this file contains the functions to open, draw and close the
  2065. X * histogram window.
  2066. X */
  2067. X
  2068. X#include "mandp.h"
  2069. X
  2070. XUBYTE HistOpen;
  2071. X
  2072. Xstruct Window          *HistWind;
  2073. X
  2074. Xstruct NewWindow NewHist = {
  2075. X   0,200-80,                 /* start position           */
  2076. X   280,80,                   /* width, height            */
  2077. X   (UBYTE) 0, (UBYTE) -1,    /* detail pen, block pen    */
  2078. X   NULL,                     /* IDCMP flags */
  2079. X                             /* MandWind flags */
  2080. X   WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|NOCAREREFRESH|SMART_REFRESH,
  2081. X   (struct Gadget *) NULL,   /* first gadget             */
  2082. X   (struct Image *) NULL,    /* user checkmark           */
  2083. X   (UBYTE *) "Histogram",     /* window title             */
  2084. X   (struct Screen *) NULL,   /* pointer to screen        */
  2085. X   (struct BitMap *) NULL,   /* pointer to superbitmap   */
  2086. X   80,80,-1,-1,              /* sizing                   */
  2087. X   CUSTOMSCREEN              /* type of screen           */
  2088. X   };
  2089. X
  2090. Xstruct Histogram *
  2091. XAllocHist( size )
  2092. X  int size;
  2093. X{
  2094. X  struct Histogram *Hist;
  2095. X
  2096. X  Hist = AllocHistStruct();
  2097. X
  2098. X  if (Hist != NULL) {
  2099. X
  2100. X    if (Hist->Table == NULL) {
  2101. X
  2102. X      Hist->Table = AllocHistTable(size);
  2103. X
  2104. X      if (Hist->Table == NULL) {
  2105. X
  2106. X        FreeHistStruct(Hist);
  2107. X        return( NULL );
  2108. X      }
  2109. X
  2110. X      Hist->TableSize = size;
  2111. X    }
  2112. X  }
  2113. X  return( Hist );
  2114. X}
  2115. X
  2116. XFreeHist( Hist )
  2117. X  struct Histogram *Hist;
  2118. X{
  2119. X  if (Hist) {
  2120. X
  2121. X    if (Hist->Table) {
  2122. X      FreeHistTable( Hist );
  2123. X    }
  2124. X    FreeHistStruct( Hist );
  2125. X  }
  2126. X}
  2127. X
  2128. XReDoHist( Pict )
  2129. X  register struct Picture *Pict;
  2130. X{
  2131. X  if (Pict == NULL || Pict->Counts == NULL ||
  2132. X      Pict->Flags & NO_RAM_GENERATE || HistWind == NULL) {
  2133. X
  2134. X    return(UNSUCCESSFUL );
  2135. X  }
  2136. X  CalcHist(Pict);
  2137. X  PlotHist(Pict);
  2138. X}
  2139. X
  2140. X/*
  2141. X *
  2142. X */
  2143. XCalcHist(Pict)
  2144. X  register struct Picture *Pict;
  2145. X{
  2146. X  register int i, n, size, *Table;
  2147. X  register SHORT *Counts;
  2148. X
  2149. X  /* make sure the histogram is available */
  2150. X
  2151. X  if (Pict->Hist) {
  2152. X    FreeHist( Pict->Hist );
  2153. X    Pict->Hist = NULL;
  2154. X  }
  2155. X
  2156. X  if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE ||
  2157. X      Pict->Counts == NULL) {
  2158. X
  2159. X    return;
  2160. X  }
  2161. X
  2162. X  Pict->Hist = AllocHist( Pict->MaxIteration );
  2163. X
  2164. X  if (Pict->Hist == NULL) {
  2165. X    return;
  2166. X  }
  2167. X
  2168. X  Table = Pict->Hist->Table;
  2169. X  size  = Pict->Hist->TableSize;
  2170. X
  2171. X  for (i = 0; i < size; i++) {
  2172. X    Table[i] = 0;
  2173. X  }
  2174. X
  2175. X  Counts = Pict->Counts;
  2176. X  size   = Pict->CountX*Pict->CountY;
  2177. X
  2178. X  for (i = 0; i < size; i++) {
  2179. X
  2180. X    if ( (n = *Counts++) > 0 && n < Pict->Hist->TableSize) {
  2181. X
  2182. X      Table[ n ]++;
  2183. X    }
  2184. X  }
  2185. X}
  2186. X
  2187. XPlotHist( Pict )
  2188. X  struct Picture *Pict;
  2189. X{
  2190. X  register struct Histogram *Hist;
  2191. X  int *Table; int  Size;
  2192. X  int  max, locmax, maxnum;
  2193. X
  2194. X  struct IntuiText *intui;
  2195. X
  2196. X  BorderWindow( HistWind );
  2197. X
  2198. X  Hist = Pict->Hist;
  2199. X
  2200. X  if (Hist == NULL) {
  2201. X    return;
  2202. X  }
  2203. X
  2204. X  Table = (int *) Hist->Table;
  2205. X  Size  = Hist->TableSize;
  2206. X
  2207. X  /* Find Max of all iteration counts */
  2208. X
  2209. X  { int i,n;
  2210. X
  2211. X    max = 0;
  2212. X
  2213. X    for (i = 0; i < Size; i++) {
  2214. X      if ((n = *Table++) > max) {
  2215. X        max = n;
  2216. X      }
  2217. X    }
  2218. X  }
  2219. X
  2220. X#define BOX_BOT  24
  2221. X#define BOX_LEFT 17
  2222. X#define BOX_TOP  22
  2223. X
  2224. X  Table = (int *) Hist->Table;
  2225. X
  2226. X  /* Plot scaled versions of this histogram */
  2227. X
  2228. X  { int bot,right,half;
  2229. X    int i, j, k, n, height,width;
  2230. X    int num_entries;
  2231. X    float scale;
  2232. X    register struct RastPort *Rp = HistWind->RPort;
  2233. X
  2234. X    if (XScale) {
  2235. X      k = 2;
  2236. X    } else {
  2237. X      k = 4;
  2238. X    }
  2239. X
  2240. X    num_entries = 1024/k;
  2241. X    right = BOX_LEFT + num_entries;
  2242. X    half = num_entries/2 + BOX_LEFT;
  2243. X    bot  = HistWind->Height - BOX_BOT;
  2244. X    scale = (float)(bot-BOX_TOP)/(float)max;
  2245. X
  2246. X    Rp = HistWind->RPort;
  2247. X
  2248. X    SetAPen(  Rp, NORMALPEN );
  2249. X    RectFill( Rp, LEFTMARG, TOPMARG, HistWind->Width-2, HistWind->Height-2);
  2250. X
  2251. X    /* Draw plot border */
  2252. X
  2253. X    SetAPen(Rp,SHADOWPEN);
  2254. X    Move(Rp,right+1,  bot+1);     /* Lower right */
  2255. X    Draw(Rp,right+1,  BOX_TOP);   /* Upper right */
  2256. X    Draw(Rp,BOX_LEFT,BOX_TOP);   /* Upper left  */
  2257. X    Draw(Rp,BOX_LEFT,bot+1);     /* Lower left  */
  2258. X    Draw(Rp,right+1,  bot+1);     /* Lower right */
  2259. X
  2260. X    Move(Rp,BOX_LEFT,bot+2);     /* Lower left tic */
  2261. X    Draw(Rp,BOX_LEFT,bot+3);
  2262. X
  2263. X    /* Do altitude tick marks */
  2264. X
  2265. X    for (i = 0; i < num_entries; i += 16<<XScale) {
  2266. X      Move(Rp, right - i + 1, bot+2);
  2267. X      Draw(Rp, right - i + 1, bot+3);
  2268. X    }
  2269. X
  2270. X    intui = ShadowIntui("1023", BOX_LEFT-16, bot + 5);
  2271. X    PrintIText( Rp, intui, 0, 0);
  2272. X    FreeIntui(intui);
  2273. X
  2274. X    intui = ShadowIntui("512", half-12, bot + 5);
  2275. X    PrintIText( Rp, intui, 0, 0);
  2276. X    FreeIntui(intui);
  2277. X
  2278. X    intui = ShadowIntui("0", right-4, bot + 5);
  2279. X    PrintIText( Rp, intui, 0, 0);
  2280. X    FreeIntui(intui);
  2281. X
  2282. X    intui = ShadowIntui("Height", half-24, bot + 13);
  2283. X    PrintIText( Rp, intui, 0, 0);
  2284. X    FreeIntui(intui);
  2285. X
  2286. X    intui = ShadowIntui("Percentage (10%/Tick)", half-84, BOX_TOP-11);
  2287. X    PrintIText( Rp, intui, 0, 0);
  2288. X    FreeIntui(intui);
  2289. X
  2290. X    /* Do percentage tick marks */
  2291. X
  2292. X    SetAPen(Rp,HIGHLIGHTPEN);
  2293. X    Move(Rp,right+1,  BOX_TOP-1); /* right */
  2294. X    Draw(Rp,right+1,  BOX_TOP-2);
  2295. X    Move(Rp,BOX_LEFT,BOX_TOP-1); /* left  */
  2296. X    Draw(Rp,BOX_LEFT,BOX_TOP-2);
  2297. X
  2298. X    { int tick = Pict->CountX*Pict->CountY/10;
  2299. X      int thresh, cur;
  2300. X
  2301. X      cur = 0;
  2302. X      thresh = tick;
  2303. X
  2304. X      for (i = Size-1; i >= 0; i--) {
  2305. X        cur += Table[i];
  2306. X        if (cur > thresh) {
  2307. X          Move(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-1);
  2308. X          Draw(Rp, right - (i/(4>>XScale)) + 1, BOX_TOP-2);
  2309. X          thresh += tick;
  2310. X        }
  2311. X      }
  2312. X    }
  2313. X
  2314. X    for (i = 0; i < Size; i += k) {
  2315. X
  2316. X      n = Table[i];
  2317. X      locmax = n;
  2318. X      maxnum = i;
  2319. X
  2320. X      for (j = 0; j < 4; j++) {
  2321. X
  2322. X        n = Table[i+j];
  2323. X
  2324. X        if (n > locmax) {
  2325. X          locmax = n;
  2326. X          maxnum = i+j;
  2327. X        }
  2328. X      }
  2329. X
  2330. X      if ( locmax > 0 ) {
  2331. X
  2332. X        height = bot - (int) (scale * locmax);
  2333. X
  2334. X        if (right   < HistWind->Width && height >= 0 &&
  2335. X            height < HistWind->Height) {
  2336. X
  2337. X          SetAPen( Rp, Pict->ClrXlate[maxnum] );
  2338. X
  2339. X          Move(Rp, right, bot);
  2340. X          Draw(Rp, right, height);
  2341. X        }
  2342. X      }
  2343. X      right -= 1;
  2344. X    }
  2345. X  }
  2346. X}
  2347. X
  2348. XAutoContour( Pict, Mode )
  2349. X  struct Picture *Pict;
  2350. X{
  2351. X  int num_conts,i,j,prev_i;
  2352. X
  2353. X  float tick;
  2354. X  float thresh, cur;
  2355. X
  2356. X  if (Pict == NULL || Pict->Flags & NO_RAM_GENERATE ||
  2357. X      Pict->Counts == NULL) {
  2358. X    return;
  2359. X  }
  2360. X
  2361. X  CalcHist(Pict);
  2362. X
  2363. X  if (Pict->Hist == NULL)
  2364. X    return;
  2365. X
  2366. X  /* find pattern range length */
  2367. X
  2368. X  for (num_conts = 255; num_conts >= 0 && Pict->Pens[num_conts] == 1;
  2369. X       num_conts--);
  2370. X
  2371. X  if (num_conts == 0)
  2372. X    return;
  2373. X
  2374. X  /* Set up contours */
  2375. X
  2376. X  j = 0;
  2377. X
  2378. X  for (i = 0 ; i < Pict->Hist->TableSize - 1; i++) {
  2379. X     j += Pict->Hist->Table[i];
  2380. X  }
  2381. X
  2382. X  thresh = tick = (float) (j) / (float) num_conts;
  2383. X  cur = 0.0;
  2384. X
  2385. X  Pict->Heights[0] = Pict->MaxIteration;
  2386. X  j = 1;
  2387. X  prev_i = 0;
  2388. X
  2389. X  for (i = Pict->Hist->TableSize - 2; i >= 0 && j < num_conts-1; i--) {
  2390. X
  2391. X    cur += Pict->Hist->Table[i];
  2392. X
  2393. X    if (cur > thresh) {
  2394. X
  2395. X      Pict->Heights[j++] = i;
  2396. X
  2397. X      if (Mode == 1 && i+1 == prev_i) {
  2398. X        break;   /* out of the loop */
  2399. X      }
  2400. X      prev_i = i;
  2401. X
  2402. X      while ( cur > thresh )
  2403. X        thresh += tick;
  2404. X    }
  2405. X  }
  2406. X  if (i < 0)
  2407. X    i = 0;
  2408. X
  2409. X  for (; j < num_conts-1; j++) {
  2410. X
  2411. X    if (i > 0) i--;
  2412. X
  2413. X    Pict->Heights[j] = i;
  2414. X  }
  2415. X  Pict->Heights[j] = 0;
  2416. X  if (ContWind) {
  2417. X    ModAll();
  2418. X  }
  2419. X  ReColor( Pict );
  2420. X}
  2421. X
  2422. X/*
  2423. X * Open the Hist window
  2424. X */
  2425. XOpenHistWind()
  2426. X{
  2427. X
  2428. X  if (CurPict == NULL)
  2429. X    return;
  2430. X
  2431. X  if ( HistWind == NULL ) {
  2432. X
  2433. X    HistWind = OpenMyWind( &NewHist, screen, NULL,280<<XScale,96+32*YScale);
  2434. X
  2435. X    if ( HistWind == NULL ) {
  2436. X      return;
  2437. X    }
  2438. X  } else {
  2439. X    WindowToFront( HistWind );
  2440. X  }
  2441. X  ReDoHist(CurPict);
  2442. X  HistOpen = 1;
  2443. X} /* OpenHistWind */
  2444. X
  2445. X/*
  2446. X * Close the Hist window
  2447. X */
  2448. XCloseHistWind()
  2449. X{
  2450. X  if (HistWind != NULL) {
  2451. X
  2452. X    NewHist.LeftEdge = HistWind->LeftEdge;
  2453. X    NewHist.TopEdge  = HistWind->TopEdge;
  2454. X
  2455. X    CloseMyWind(HistWind,NULL);
  2456. X  }
  2457. X  HistWind = NULL;
  2458. X} /* CloseHistWind */
  2459. X
  2460. SHAR_EOF
  2461. echo "extracting iffw.c"
  2462. sed 's/^X//' << \SHAR_EOF > iffw.c
  2463. X/*----------------------------------------------------------------------*
  2464. X * IFFW.C  Support routines for writing IFF-85 files.          1/23/86
  2465. X * (IFF is Interchange Format File.)
  2466. X *
  2467. X * By Jerry Morrison and Steve Shaw, Electronic Arts.
  2468. X * This software is in the public domain.
  2469. X *
  2470. X * This version for the Commodore-Amiga computer.
  2471. X *----------------------------------------------------------------------*/
  2472. X#include "iff/iff.h"
  2473. X#include "iff/gio.h"
  2474. X
  2475. X/* ---------- IFF Writer -----------------------------------------------*/
  2476. X
  2477. X/* A macro to test if a chunk size is definite, i.e. not szNotYetKnown.*/
  2478. X#define Known(size)   ( (size) != szNotYetKnown )
  2479. X
  2480. X/* Yet another weird macro to make the source code simpler...*/
  2481. X#define IfIffp(expr)  {if (iffp == IFF_OKAY)  iffp = (expr);}
  2482. X
  2483. X/* ---------- OpenWIFF -------------------------------------------------*/
  2484. X
  2485. XIFFP OpenWIFF(file, new0, limit)  BPTR file; GroupContext *new0; LONG limit; {
  2486. X    register GroupContext *new = new0;
  2487. X    register IFFP iffp = IFF_OKAY;
  2488. X
  2489. X    new->parent       = NULL;
  2490. X    new->clientFrame  = NULL;
  2491. X    new->file         = file;
  2492. X    new->position     = 0;
  2493. X    new->bound        = limit;
  2494. X    new->ckHdr.ckID   = NULL_CHUNK;  /* indicates no current chunk */
  2495. X    new->ckHdr.ckSize = new->bytesSoFar = 0;
  2496. X
  2497. X    if (0 > Seek(file, 0, OFFSET_BEGINNING))    /* Go to start of the file.*/
  2498. X        iffp = DOS_ERROR;
  2499. X    else if ( Known(limit) && IS_ODD(limit) )
  2500. X        iffp = CLIENT_ERROR;
  2501. X    return(iffp);
  2502. X    }
  2503. X
  2504. X/* ---------- StartWGroup ----------------------------------------------*/
  2505. XIFFP StartWGroup(parent, groupType, groupSize, subtype, new)
  2506. X      GroupContext *parent, *new; ID groupType, subtype; LONG groupSize;  {
  2507. X    register IFFP iffp;
  2508. X
  2509. X    iffp = PutCkHdr(parent, groupType, groupSize);
  2510. X    IfIffp( IFFWriteBytes(parent, (BYTE *)&subtype, sizeof(ID)) );
  2511. X    IfIffp( OpenWGroup(parent, new) );
  2512. X    return(iffp);
  2513. X    }
  2514. X
  2515. X/* ---------- OpenWGroup -----------------------------------------------*/
  2516. XIFFP OpenWGroup(parent0, new0)  GroupContext *parent0, *new0; {
  2517. X    register GroupContext *parent = parent0;
  2518. X    register GroupContext *new    = new0;
  2519. X    register LONG ckEnd;
  2520. X    register IFFP iffp = IFF_OKAY;
  2521. X
  2522. X    new->parent       = parent;
  2523. X    new->clientFrame  = parent->clientFrame;
  2524. X    new->file         = parent->file;
  2525. X    new->position     = parent->position;
  2526. X    new->bound        = parent->bound;
  2527. X    new->ckHdr.ckID   = NULL_CHUNK;
  2528. X    new->ckHdr.ckSize = new->bytesSoFar = 0;
  2529. X
  2530. X    if ( Known(parent->ckHdr.ckSize) ) {
  2531. X        ckEnd = new->position + ChunkMoreBytes(parent);
  2532. X        if ( new->bound == szNotYetKnown || new->bound > ckEnd )
  2533. X            new->bound = ckEnd;
  2534. X        };
  2535. X
  2536. X    if ( parent->ckHdr.ckID == NULL_CHUNK || /* not currently writing a chunk*/
  2537. X         IS_ODD(new->position) ||
  2538. X         (Known(new->bound) && IS_ODD(new->bound)) )
  2539. X        iffp = CLIENT_ERROR;
  2540. X    return(iffp);
  2541. X    }
  2542. X
  2543. X/* ---------- CloseWGroup ----------------------------------------------*/
  2544. XIFFP CloseWGroup(old0)  GroupContext *old0; {
  2545. X    register GroupContext *old = old0;
  2546. X    IFFP iffp = IFF_OKAY;
  2547. X
  2548. X    if ( old->ckHdr.ckID != NULL_CHUNK )  /* didn't close the last chunk */
  2549. X        iffp = CLIENT_ERROR;
  2550. X    else if ( old->parent == NULL ) {     /* top level file context */
  2551. X        if (GWriteFlush(old->file) < 0)  iffp = DOS_ERROR;
  2552. X        }
  2553. X    else {                                /* update parent context */
  2554. X        old->parent->bytesSoFar += old->position - old->parent->position;
  2555. X        old->parent->position = old->position;
  2556. X        };
  2557. X    return(iffp);
  2558. X    }
  2559. X
  2560. X/* ---------- EndWGroup ------------------------------------------------*/
  2561. XIFFP EndWGroup(old)  GroupContext *old;  {
  2562. X    register GroupContext *parent = old->parent;
  2563. X    register IFFP iffp;
  2564. X
  2565. X    iffp = CloseWGroup(old);
  2566. X    IfIffp( PutCkEnd(parent) );
  2567. X    return(iffp);
  2568. X    }
  2569. X
  2570. X/* ---------- PutCk ----------------------------------------------------*/
  2571. XIFFP PutCk(context, ckID, ckSize, data)
  2572. X      GroupContext *context; ID ckID; LONG ckSize; BYTE *data; {
  2573. X    register IFFP iffp = IFF_OKAY;
  2574. X
  2575. X    if ( ckSize == szNotYetKnown )
  2576. X        iffp = CLIENT_ERROR;
  2577. X    IfIffp( PutCkHdr(context, ckID, ckSize) );
  2578. X    IfIffp( IFFWriteBytes(context, data, ckSize) );
  2579. X    IfIffp( PutCkEnd(context) );
  2580. X    return(iffp);
  2581. X    }
  2582. X
  2583. X/* ---------- PutCkHdr -------------------------------------------------*/
  2584. XIFFP PutCkHdr(context0, ckID, ckSize)
  2585. X      GroupContext *context0;  ID ckID;  LONG ckSize; {
  2586. X    register GroupContext *context = context0;
  2587. X    LONG minPSize = sizeof(ChunkHeader); /* physical chunk >= minPSize bytes*/
  2588. X
  2589. X    /* CLIENT_ERROR if we're already inside a chunk or asked to write
  2590. X     * other than one FORM, LIST, or CAT at the top level of a file */
  2591. X    /* Also, non-positive ID values are illegal and used for error codes.*/
  2592. X    /* (We could check for other illegal IDs...)*/
  2593. X    if ( context->ckHdr.ckID != NULL_CHUNK  ||  ckID <= 0 )
  2594. X        return(CLIENT_ERROR);
  2595. X    else if (context->parent == NULL)  {
  2596. X        switch (ckID)  {
  2597. X            case FORM:  case LIST:  case CAT:  break;
  2598. X            default: return(CLIENT_ERROR);
  2599. X            }
  2600. X        if (context->position != 0)
  2601. X            return(CLIENT_ERROR);
  2602. X        }
  2603. X
  2604. X    if ( Known(ckSize) ) {
  2605. X        if ( ckSize < 0 )
  2606. X            return(CLIENT_ERROR);
  2607. X        minPSize += ckSize;
  2608. X        };
  2609. X    if ( Known(context->bound)  &&
  2610. X         context->position + minPSize > context->bound )
  2611. X        return(CLIENT_ERROR);
  2612. X
  2613. X    context->ckHdr.ckID   = ckID;
  2614. X    context->ckHdr.ckSize = ckSize;
  2615. X    context->bytesSoFar   = 0;
  2616. X    if (0 >
  2617. X        GWrite(context->file, (BYTE *)&context->ckHdr, sizeof(ChunkHeader))
  2618. X        )
  2619. X        return(DOS_ERROR);
  2620. X    context->position += sizeof(ChunkHeader);
  2621. X    return(IFF_OKAY);
  2622. X    }
  2623. X
  2624. X/* ---------- IFFWriteBytes ---------------------------------------------*/
  2625. XIFFP IFFWriteBytes(context0, data, nBytes)
  2626. X      GroupContext *context0;  BYTE *data;  LONG nBytes; {
  2627. X    register GroupContext *context = context0;
  2628. X
  2629. X    if ( context->ckHdr.ckID == NULL_CHUNK  ||  /* not in a chunk */
  2630. X         nBytes < 0  ||                         /* negative nBytes */
  2631. X         (Known(context->bound)  &&             /* overflow context */
  2632. X            context->position + nBytes > context->bound)  ||
  2633. X         (Known(context->ckHdr.ckSize)  &&      /* overflow chunk */
  2634. X            context->bytesSoFar + nBytes > context->ckHdr.ckSize) )
  2635. X        return(CLIENT_ERROR);
  2636. X
  2637. X    if (0 > GWrite(context->file, data, nBytes))
  2638. X        return(DOS_ERROR);
  2639. X
  2640. X    context->bytesSoFar += nBytes;
  2641. X    context->position   += nBytes;
  2642. X    return(IFF_OKAY);
  2643. X    }
  2644. X
  2645. X/* ---------- PutCkEnd -------------------------------------------------*/
  2646. XIFFP PutCkEnd(context0)  GroupContext *context0; {
  2647. X    register GroupContext *context = context0;
  2648. X    WORD zero = 0;      /* padding source */
  2649. X
  2650. X    if ( context->ckHdr.ckID == NULL_CHUNK )  /* not in a chunk */
  2651. X        return(CLIENT_ERROR);
  2652. X
  2653. X    if ( context->ckHdr.ckSize == szNotYetKnown ) {
  2654. X        /* go back and set the chunk size to bytesSoFar */
  2655. X        if ( 0 >
  2656. XGSeek(context->file, -(context->bytesSoFar + sizeof(LONG)), OFFSET_CURRENT) ||
  2657. X             0 >
  2658. XGWrite(context->file, (BYTE *)&context->bytesSoFar, sizeof(LONG))  ||
  2659. X             0 >
  2660. XGSeek(context->file, context->bytesSoFar, OFFSET_CURRENT)  )
  2661. X            return(DOS_ERROR);
  2662. X        }
  2663. X    else {  /* make sure the client wrote as many bytes as planned */
  2664. X        if ( context->ckHdr.ckSize != context->bytesSoFar )
  2665. X            return(CLIENT_ERROR);
  2666. X        };
  2667. X
  2668. X    /* Write a pad byte if needed to bring us up to an even boundary.
  2669. X     * Since the context end must be even, and since we haven't
  2670. X     * overwritten the context, if we're on an odd position there must
  2671. X     * be room for a pad byte. */
  2672. X    if ( IS_ODD(context->bytesSoFar) ) {
  2673. X        if ( 0 > GWrite(context->file, (BYTE *)&zero, 1) )
  2674. X            return(DOS_ERROR);
  2675. X        context->position += 1;
  2676. X        };
  2677. X
  2678. X    context->ckHdr.ckID   = NULL_CHUNK;
  2679. X    context->ckHdr.ckSize = context->bytesSoFar = 0;
  2680. X    return(IFF_OKAY);
  2681. X    }
  2682. X
  2683. SHAR_EOF
  2684. echo "End of archive 3 (of 9)"
  2685. # if you want to concatenate archives, remove anything after this line
  2686. exit
  2687.